1. 程式人生 > >zookeeper(1)

zookeeper(1)

gossip

隨筆 - 634  文章 - 3  評論 - 434
    </div><!--end: blogStats -->
</div><!--end: navigator 部落格導航欄 -->

【轉】淺談分散式服務協調技術 Zookeeper

非常好介紹Zookeeper的文章,

Google的三篇論文影響了很多很多人,也影響了很多很多系統。這三篇論文一直是分散式領域傳閱的經典。根據MapReduce,於是我們有了Hadoop;根據GFS,於是我們有了HDFS;根據BigTable,於是我們有了HBase。而在這三篇論文裡都提及Google的一個Lock Service —— Chubby,哦,於是我們有了Zookeeper。

隨著大資料的火熱,Hxx們已經變得耳熟能詳,現在作為一個開發人員如果都不知道這幾個名詞出門都好像不好意思跟人打招呼。但實際上對我們這些非大資料開發人員而言,Zookeeper是比Hxx們可能接觸到更多的一個基礎服務。但是,無奈的是它一直默默的位於二線,從來沒有Hxx們那麼耀眼。那麼到底什麼是Zookeeper呢?Zookeeper可以用來幹什麼?我們將如何使用Zookeeper?Zookeeper又是怎麼實現的?

 

什麼是Zookeeper

在Zookeeper的官網上有這麼一句話:ZooKeeper is a centralized service for maintaining configuration information, naming, providing distributed synchronization, and providing group services。

這大概描述了Zookeeper主要是一個分散式服務協調框架,實現同步服務,配置維護和命名服務等分散式應用。是一個高效能的分散式資料一致性解決方案。

通俗地講,ZooKeeper是動物園管理員,它是拿來管大象 Hadoop、鯨魚 HBase、Kafka等的管理員。

 

Zookeeper和CAP的關係

作為一個分散式系統,分割槽容錯性是一個必須要考慮的關鍵點。一個分散式系統一旦喪失了分割槽容錯性,也就表示放棄了擴充套件性。因為在分散式系統中,網路故障是經常出現的,一旦出現在這種問題就會導致整個系統不可用是絕對不能容忍的。所以,大部分分散式系統都會在保證分割槽容錯性的前提下在一致性和可用性之間做權衡。

ZooKeeper是個CP(一致性+分割槽容錯性)的,即任何時刻對ZooKeeper的訪問請求能得到一致的資料結果,同時系統對網路分割具備容錯性;但是它不能保證每次服務請求的可用性。也就是在極端環境下,ZooKeeper可能會丟棄一些請求,消費者程式需要重新請求才能獲得結果。

ZooKeeper是分散式協調服務,它的職責是保證資料在其管轄下的所有服務之間保持同步、一致;所以就不難理解為什麼ZooKeeper被設計成CP而不是AP特性的了。而且, 作為ZooKeeper的核心實現演算法Zab,就是解決了分散式系統下資料如何在多個服務之間保持同步問題的。

 

Zookeeper節點特性及節點屬性分析

Zookeeper提供基於類似於檔案系統的目錄節點樹方式的資料儲存,但是Zookeeper並不是用來專門儲存資料的,它的作用主要是用來維護和監控你儲存的資料的狀態變化。通過監控這些資料狀態的變化,從而可以達到基於資料的叢集管理。

資料模型

與Linux檔案系統不同的是,Linux檔案系統有目錄和檔案的區別,而Zookeeper的資料節點稱為ZNode,ZNode是Zookeeper中資料的最小單元,每個ZNode都可以儲存資料,同時還可以掛載子節點,因此構成了一個層次化的名稱空間,稱為樹。

Zookeeper中ZNode的節點建立時候是可以指定型別的,主要有下面幾種型別。

  • PERSISTENT:持久化ZNode節點,一旦建立這個ZNode點儲存的資料不會主動消失,除非是客戶端主動的delete。

  • EPHEMERAL:臨時ZNode節點,Client連線到Zookeeper Service的時候會建立一個Session,之後用這個Zookeeper連線例項建立該型別的znode,一旦Client關閉了Zookeeper的連線,伺服器就會清除Session,然後這個Session建立的ZNode節點都會從名稱空間消失。總結就是,這個型別的znode的生命週期是和Client建立的連線一樣的。

  • PERSISTENT_SEQUENTIAL:順序自動編號的ZNode節點,這種znoe節點會根據當前已近存在的ZNode節點編號自動加 1,而且不會隨Session斷開而消失。

  • EPEMERAL_SEQUENTIAL:臨時自動編號節點,ZNode節點編號會自動增加,但是會隨Session消失而消失

Watcher資料變更通知

Zookeeper使用Watcher機制實現分散式資料的釋出/訂閱功能。

Zookeeper的Watcher機制主要包括客戶端執行緒、客戶端WatcherManager、Zookeeper伺服器三部分。客戶端在向Zookeeper伺服器註冊的同時,會將Watcher物件儲存在客戶端的WatcherManager當中。當Zookeeper伺服器觸發Watcher事件後,會向客戶端傳送通知,客戶端執行緒從WatcherManager中取出對應的Watcher物件來執行回撥邏輯。

ACL保障資料的安全

Zookeeper內部儲存了分散式系統執行時狀態的元資料,這些元資料會直接影響基於Zookeeper進行構造的分散式系統的執行狀態,如何保障系統中資料的安全,從而避免因誤操作而帶來的資料隨意變更而導致的資料庫異常十分重要,Zookeeper提供了一套完善的ACL許可權控制機制來保障資料的安全。

我們可以從三個方面來理解ACL機制:許可權模式 Scheme、授權物件 ID、許可權 Permission,通常使用”scheme:id:permission”來標識一個有效的ACL資訊。

記憶體資料

Zookeeper的資料模型是樹結構,在記憶體資料庫中,儲存了整棵樹的內容,包括所有的節點路徑、節點資料、ACL資訊,Zookeeper會定時將這個資料儲存到磁碟上。

  • DataTree:DataTree是記憶體資料儲存的核心,是一個樹結構,代表了記憶體中一份完整的資料。DataTree不包含任何與網路、客戶端連線及請求處理相關的業務邏輯,是一個獨立的元件。

  • DataNode:DataNode是資料儲存的最小單元,其內部除了儲存了結點的資料內容、ACL列表、節點狀態之外,還記錄了父節點的引用和子節點列表兩個屬性,其也提供了對子節點列表進行操作的介面。

  • ZKDatabase:Zookeeper的記憶體資料庫,管理Zookeeper的所有會話、DataTree儲存和事務日誌。ZKDatabase會定時向磁碟dump快照資料,同時在Zookeeper啟動時,會通過磁碟的事務日誌和快照檔案恢復成一個完整的記憶體資料庫。

 

Zookeeper的實現原理分析

1. Zookeeper Service網路結構

Zookeeper的工作叢集可以簡單分成兩類,一個是Leader,唯一一個,其餘的都是follower,如何確定Leader是通過內部選舉確定的。

  • Leader和各個follower是互相通訊的,對於Zookeeper系統的資料都是儲存在記憶體裡面的,同樣也會備份一份在磁碟上。

  • 如果Leader掛了,Zookeeper叢集會重新選舉,在毫秒級別就會重新選舉出一個Leader。

  • 叢集中除非有一半以上的Zookeeper節點掛了,Zookeeper Service才不可用。

2. Zookeeper讀寫資料

  • 寫資料,一個客戶端進行寫資料請求時,如果是follower接收到寫請求,就會把請求轉發給Leader,Leader通過內部的Zab協議進行原子廣播,直到所有Zookeeper節點都成功寫了資料後(記憶體同步以及磁碟更新),這次寫請求算是完成,然後Zookeeper Service就會給Client發回響應。

  • 讀資料,因為叢集中所有的Zookeeper節點都呈現一個同樣的名稱空間檢視(就是結構資料),上面的寫請求已經保證了寫一次資料必須保證叢集所有的Zookeeper節點都是同步名稱空間的,所以讀的時候可以在任意一臺Zookeeper節點上。

3. Zookeeper工作原理

Zab協議

Zookeeper的核心是廣播,這個機制保證了各個Server之間的同步。實現這個機制的協議叫做Zab協議。

Zab(ZooKeeper Atomic Broadcast)原子訊息廣播協議作為資料一致性的核心演算法,Zab協議是專為Zookeeper設計的支援崩潰恢復原子訊息廣播演算法。

Zab協議核心如下:

所有的事務請求必須一個全域性唯一的伺服器(Leader)來協調處理,叢集其餘的伺服器稱為follower伺服器。Leader伺服器負責將一個客戶端請求轉化為事務提議(Proposal),並將該proposal分發給叢集所有的follower伺服器。之後Leader伺服器需要等待所有的follower伺服器的反饋,一旦超過了半數的follower伺服器進行了正確反饋後,那麼Leader伺服器就會再次向所有的follower伺服器分發commit訊息,要求其將前一個proposal進行提交。

Zab模式

Zab協議包括兩種基本的模式:崩潰恢復訊息廣播

  • 當整個服務框架啟動過程中或Leader伺服器出現網路中斷、崩潰退出與重啟等異常情況時,Zab協議就會進入恢復模式並選舉產生新的Leader伺服器。

  • 當選舉產生了新的Leader伺服器,同時叢集中已經有過半的機器與該Leader伺服器完成了狀態同步之後,Zab協議就會退出恢復模式,狀態同步是指資料同步,用來保證叢集在過半的機器能夠和Leader伺服器的資料狀態保持一致。

  • 當叢集中已經有過半的Follower伺服器完成了和Leader伺服器的狀態同步,那麼整個服務框架就可以進入訊息廣播模式。

  • 當一臺同樣遵守Zab協議的伺服器啟動後加入到叢集中,如果此時叢集中已經存在一個Leader伺服器在負責進行訊息廣播,那麼加入的伺服器就會自覺地進入資料恢復模式:找到Leader所在的伺服器,並與其進行資料同步,然後一起參與到訊息廣播流程中去。

Zookeeper只允許唯一的一個Leader伺服器來進行事務請求的處理,Leader伺服器在接收到客戶端的事務請求後,會生成對應的事務提議併發起一輪廣播協議,而如果叢集中的其他機器收到客戶端的事務請求後,那麼這些非Leader伺服器會首先將這個事務請求轉發給Leader伺服器。

訊息廣播

Zab協議的訊息廣播過程使用是一個原子廣播協議,類似一個2PC提交過程。具體的:

  • ZooKeeper使用單一主程序Leader用於處理客戶端所有事務請求,並採用Zab的原子廣播協議,將伺服器資料狀態變更以事務Proposal的形式廣播Follower上,因此能很好的處理客戶端的大量併發請求。

  • 另一方面,由於事務間可能存在著依賴關係,Zab協議保證Leader廣播的變更序列被順序的處理,有些狀態的變更必須依賴於比它早生成的那些狀態變更。

  • 最後,考慮到主程序Leader在任何時候可能崩潰或者異常退出, 因此Zab協議還要Leader程序崩潰的時候可以重新選出Leader並且保證資料的完整性;Follower收到Proposal後,寫到磁碟,返回Ack。Leader收到大多數ACK後,廣播Commit訊息,自己也提交該訊息。Follower收到Commit之後,提交該訊息。

Zab協議簡化了2PC事務提交:

  • 去除中斷邏輯移除,follower要麼ack,要麼拋棄Leader。

  • Leader不需要所有的Follower都響應成功,只要一個多數派Ack即可。

崩潰恢復

上面我們講了Zab協議在正常情況下的訊息廣播過程,那麼一旦Leader伺服器出現崩潰或者與過半的follower伺服器失去聯絡,就進入崩潰恢復模式。

恢復模式需要重新選舉出一個新的Leader,讓所有的Server都恢復到一個正確的狀態。

 

Zookeeper實踐,共享鎖,Leader選舉

分散式鎖用於控制分散式系統之間同步訪問共享資源的一種方式,可以保證不同系統訪問一個或一組資源時的一致性,主要分為排它鎖和共享鎖。

  • 排它鎖又稱為寫鎖或獨佔鎖,若事務T1對資料物件O1加上了排它鎖,那麼在整個加鎖期間,只允許事務T1對O1進行讀取和更新操作,其他任何事務都不能再對這個資料物件進行任何型別的操作,直到T1釋放了排它鎖。

  • 共享鎖又稱為讀鎖,若事務T1對資料物件O1加上共享鎖,那麼當前事務只能對O1進行讀取操作,其他事務也只能對這個資料物件加共享鎖,直到該資料物件上的所有共享鎖都被釋放。

推薦文章:基於Zk實現分散式鎖

Leader選舉

Leader選舉是保證分散式資料一致性的關鍵所在。當Zookeeper叢集中的一臺伺服器出現以下兩種情況之一時,需要進入Leader選舉。

  • 伺服器初始化啟動。

  • 伺服器執行期間無法和Leader保持連線。

Zookeeper在3.4.0版本後只保留了TCP版本的 FastLeaderElection 選舉演算法。當一臺機器進入Leader選舉時,當前叢集可能會處於以下兩種狀態:

  • 叢集中已存在Leader。

  • 叢集中不存在Leader。

對於叢集中已經存在Leader而言,此種情況一般都是某臺機器啟動得較晚,在其啟動之前,叢集已經在正常工作,對這種情況,該機器試圖去選舉Leader時,會被告知當前伺服器的Leader資訊,對於該機器而言,僅僅需要和Leader機器建立起連線,並進行狀態同步即可。

而在叢集中不存在Leader情況下則會相對複雜,其步驟如下:

(1) 第一次投票。無論哪種導致進行Leader選舉,叢集的所有機器都處於試圖選舉出一個Leader的狀態,即LOOKING狀態,LOOKING機器會向所有其他機器傳送訊息,該訊息稱為投票。投票中包含了SID(伺服器的唯一標識)和ZXID(事務ID),(SID, ZXID)形式來標識一次投票資訊。假定Zookeeper由5臺機器組成,SID分別為1、2、3、4、5,ZXID分別為9、9、9、8、8,並且此時SID為2的機器是Leader機器,某一時刻,1、2所在機器出現故障,因此叢集開始進行Leader選舉。在第一次投票時,每臺機器都會將自己作為投票物件,於是SID為3、4、5的機器投票情況分別為(3, 9),(4, 8), (5, 8)。

(2) 變更投票。每臺機器發出投票後,也會收到其他機器的投票,每臺機器會根據一定規則來處理收到的其他機器的投票,並以此來決定是否需要變更自己的投票,這個規則也是整個Leader選舉演算法的核心所在,其中術語描述如下

  • vote_sid:接收到的投票中所推舉Leader伺服器的SID。

  • vote_zxid:接收到的投票中所推舉Leader伺服器的ZXID。

  • self_sid:當前伺服器自己的SID。

  • self_zxid:當前伺服器自己的ZXID。

每次對收到的投票的處理,都是對(vote_sid, vote_zxid)和(self_sid, self_zxid)對比的過程。

  • 規則一:如果vote_zxid大於self_zxid,就認可當前收到的投票,並再次將該投票傳送出去。

  • 規則二:如果vote_zxid小於self_zxid,那麼堅持自己的投票,不做任何變更。

  • 規則三:如果vote_zxid等於self_zxid,那麼就對比兩者的SID,如果vote_sid大於self_sid,那麼就認可當前收到的投票,並再次將該投票傳送出去。

  • 規則四:如果vote_zxid等於self_zxid,並且vote_sid小於self_sid,那麼堅持自己的投票,不做任何變更。

  • 結合上面規則,給出下面的叢集變更過程。

(3) 確定Leader。經過第二輪投票後,叢集中的每臺機器都會再次接收到其他機器的投票,然後開始統計投票,如果一臺機器收到了超過半數的相同投票,那麼這個投票對應的SID機器即為Leader。此時Server3將成為Leader。

由上面規則可知,通常那臺伺服器上的資料越新(ZXID會越大),其成為Leader的可能性越大,也就越能夠保證資料的恢復。如果ZXID相同,則SID越大機會越大。

 

「 淺談大規模分散式系統中那些技術點」系列文章:

 

Reference

http://www.cnblogs.com/yuyijq/p/3391945.html

http://www.cnblogs.com/kms1989/p/5504505.html

http://www.hollischuang.com/archives/1275

http://www.jianshu.com/p/bf32e44d3113

http://www.jianshu.com/p/4654bdbb8792

http://www.jianshu.com/p/8fba732af0cd

http://www.jianshu.com/p/6af7362701c5

http://www.jianshu.com/p/6929446d3b10

http://www.jianshu.com/p/5dce97c9ba85

http://www.cnblogs.com/sunddenly/articles/4073157.html

http://www.dczou.com/viemall/454.html


轉載請並標註: “本文轉載自 linkedkeeper.com (文/張鬆然)”

 
好文要頂 關注我 收藏該文
關注 - 22
粉絲 - 366 +加關注 0 0 currentDiggType = 0; « 上一篇: JVM Debugger Memory View for IntelliJ IDEA
» 下一篇: 【轉】Intellij IDEA除錯功能
posted @ 2017-07-26 09:54 閱讀( 1276) 評論( 0) 編輯 收藏 重新整理評論 重新整理頁面 返回頂部 註冊使用者登入後才能發表評論,請 登入註冊訪問網站首頁。 【推薦】超50萬VC++原始碼: 大型組態工控、電力模擬CAD與GIS原始碼庫!
【前端】SpreadJS表格控制元件,可嵌入應用開發的線上Excel
【免費】程式設計師21天搞定英文文件閱讀
【推薦】如何快速搭建人工智慧應用?
qcloud0814 最新IT新聞:
· 錘子吳德周:初期低估了TNT的開發難度 但系統會持續做
· 網易:2018年11月30日零點起正式停止網易部落格運營
· 基於opencv和python的手指識別及追蹤
· 一文看懂京東智慧城市佈局:城市計算的“方法論”
· 軟銀願景基金投資眾安線上 幫助其佈局國際市場
» 更多新聞… 華為雲HC 最新知識庫文章:
· 一個故事看懂“區塊鏈”
· 被踢出去的使用者
· 成為一個有目標的學習者
· 歷史轉折中的“杭派工程師”
· 如何提高程式碼質量?
» 更多知識庫文章… 歷史上的今天:
2016-07-26 索引的特點及使用
fixPostBody(); setTimeout(function () { incrementViewCount(cb_entryId); }, 50); deliverAdT2(); deliverAdC1(); deliverAdC2(); loadNewsAndKb(); loadBlogSignature(); LoadPostInfoBlock(cb_blogId, cb_entryId, cb_blogApp, cb_blogUserGuid); GetPrevNextPost(cb_entryId, cb_blogId, cb_entryCreatedDate, cb_postType); loadOptUnderPost(); GetHistoryToday(cb_blogId, cb_blogApp, cb_entryCreatedDate);

</div><!--end: forFlow -->
</div><!--end: mainContent 主體內容容器-->

<div id="sideBar">
    <div id="sideBarMain">

公告

暱稱:
園齡: 10年2個月
粉絲: 366
關注: 22 +加關注
        <div id="blog-calendar" style=""><table id="blogCalendar" class="Cal" cellspacing="0" cellpadding="0" title="Calendar">
<tbody><tr><td colspan="7"><table class="CalTitle" cellspacing="0">
    <tbody><tr><td class="CalNextPrev"><a href="javascript:void(0);" onclick="loadBlogCalendar('2018/07/01');return false;">&lt;</a></td><td align="center">2018年8月</td><td class="CalNextPrev" align="right"><a href="javascript:void(0);" onclick="loadBlogCalendar('2018/09/01');return false;">&gt;</a></td></tr>
</tbody></table></td></tr><tr><th class="CalDayHeader" align="center" abbr="日" scope="col">日</th><th class="CalDayHeader" align="center" abbr="一" scope="col">一</th><th class="CalDayHeader" align="center" abbr="二" scope="col">二</th><th class="CalDayHeader" align="center" abbr="三" scope="col">三</th><th class="CalDayHeader" align="center" abbr="四" scope="col">四</th><th class="CalDayHeader" align="center" abbr="五" scope="col">五</th><th class="CalDayHeader" align="center" abbr="六" scope="col">六</th></tr><tr><td class="CalOtherMonthDay" align="center">29</td><td class="CalOtherMonthDay" align="center">30</td><td class="CalOtherMonthDay" align="center">31</td><td align="center">1</td><td align="center">2</td><td align="center">3</td><td class="CalWeekendDay" align="center">4</td></tr><tr><td class="CalWeekendDay" align="center">5</td><td align="center">6</td><td align="center">7</td><td align="center"><a href="https://www.cnblogs.com/gossip/archive/2018/08/08.html"><u>8</u></a></td><td align="center">9</td><td align="center">10</td><td class="CalWeekendDay" align="center">11</td></tr><tr><td class="CalWeekendDay" align="center">12</td><td align="center">13</td><td align="center">14</td><td align="center">15</td><td align="center">16</td><td align="center">17</td><td class="CalWeekendDay" align="center">18</td></tr><tr><td class="CalWeekendDay" align="center">19</td><td align="center">20</td><td class="CalTodayDay" align="center">21</td><td align="center">22</td><td align="center">23</td><td align="center">24</td><td class="CalWeekendDay" align="center">25</td></tr><tr><td class="CalWeekendDay" align="center">26</td><td align="center">27</td><td align="center">28</td><td align="center">29</td><td align="center">30</td><td align="center">31</td><td class="CalOtherMonthDay" align="center">1</td></tr><tr><td class="CalOtherMonthDay" align="center">2</td><td class="CalOtherMonthDay" align="center">3</td><td class="CalOtherMonthDay" align="center">4</td><td class="CalOtherMonthDay" align="center">5</td><td class="CalOtherMonthDay" align="center">6</td><td class="CalOtherMonthDay" align="center">7</td><td class="CalOtherMonthDay" align="center">8</td></tr>

        <div id="leftcontentcontainer">
            <div id="blog-sidecolumn"><div id="sidebar_search" class="sidebar-block">

搜尋

   

常用連結

我的標籤

隨筆分類(370)

隨筆檔案(634)

積分與排名

  • 積分 - 585436
  • 排名 - 209

最新評論


閱讀排行榜

評論排行榜