二十7、Zookeeper的內部原理與ZAB協議

本文主要講述Zookeeper的內部原理以及ZAB協議,Zookeeper算是大數據中的一個協做框架,比較簡單,本文應該是Zookeeper部分的最後一篇文章。關注專欄《破繭成蝶——大數據篇》,查看更多相關的內容~html


目錄node

1、Zookeeper的內部原理算法

1.1 節點類型服務器

1.2 Stat結構體網絡

1.3 監聽器session

1.4 寫數據流程架構

1.5 Zookeeper的選舉機制框架

2、ZAB協議異步

2.1 ZAB協議是什麼分佈式

2.2 ZAB協議的做用

2.3 ZAB協議的原理

2.4 ZAB協議的工做

2.4.1 消息廣播

2.4.2 崩潰恢復

2.5 ZAB數據同步


 

1、Zookeeper的內部原理

1.1 節點類型

Zookeeper的節點類型能夠分爲兩種:持久型和短暫型。持久型指當客戶端與服務器斷開鏈接後,該節點不會刪除;短暫型指當客戶端與服務器斷開鏈接後,該節點也會隨之刪除。

1.2 Stat結構體

 Stat結構體在《二11、Zookeeper的命令行操做》中已經有提到過了,可是這裏得再次不厭其煩的說一下。

       (1)cZxid:建立節點的事務zxid。每次修改ZooKeeper狀態都會收到一個zxid形式的時間戳,也就是ZooKeeper事務ID。事務ID是ZooKeeper中全部修改總的次序。每一個修改都有惟一的zxid,若是zxid1小於zxid2,那麼zxid1在zxid2以前發生。
       (2)ctime:znode被建立的毫秒數(從1970年開始)。
       (3)mZxid:znode最後更新的事務zxid。
       (4)mtime:znode最後修改的毫秒數(從1970年開始)。
       (5)pZxid:znode最後更新的子節點zxid。
       (6)cversion:znode子節點變化號,znode子節點修改次數。
       (7)dataVersion:znode數據變化號。
       (8)aclVersion:znode訪問控制列表的變化號。
       (9)ephemeralOwner:若是是臨時節點,這個是znode擁有者的session id。若是不是臨時節點則是0。
       (10)dataLength:znode的數據長度。
       (11)numChildren:znode子節點數量。









1.3 監聽器

一、首先在main()線程中建立Zookeeper客戶端,這時會同時建立兩個線程:一個用於網絡鏈接通訊(A),一個用於監聽(B)。

二、經過A線程將註冊的監聽事件發送個Zookeeper,這時Zookeeper會將註冊的監聽事件添加到註冊監聽器列表。

三、Zookeeper監聽到有數據或者路徑等等的變化,就會將這個消息發送給B線程。

1.4 寫數據流程

一、客戶端向Zookeeper的服務器上寫數據,首先會發送一個寫請求。

二、若是接收到該請求的服務器(A)不是Leader服務器,那麼它會將這個請求轉發給Leader服務器,這時Leader服務器會將請求廣播給集羣內的其餘服務器。各個服務器會將寫請求加入待寫隊列,並向Leader服務器發送成功的信息。

三、當Leader服務器收到半數以上的Follower服務器的成功信息後,說明該寫操做能夠執行。這是Leader會向各個Follower發送提交信息,各個Follower收到信息後,會落實隊列裏面的寫請求,此時寫入成功。

四、服務器A通知客戶端數據寫入成功。

1.5 Zookeeper的選舉機制

選舉機制遵循半數機制,即:集羣中半數以上機器存活,集羣就是可用狀態,因此Zookeeper適合安裝奇數臺服務器。Zookeeper雖然在配置文件中並無指定Master和Slave。可是,Zookeeper工做時,是有一個節點爲Leader,其餘則爲Follower,Leader是經過內部的選舉機制臨時產生的。例若有五臺服務器(A-E)組成的Zookeeper集羣,同時它們都是最新啓動的,也就是沒有歷史數據,在存放數據量這一點上,都是同樣的。假設這些服務器依次啓動,那麼會發生下面的狀況:

一、服務器A啓動,發起一次選舉。服務器A投本身一票。此時服務器A票數一票,不夠半數以上(3票),選舉沒法完成,服務器A狀態保持爲LOOKING。

二、服務器B啓動,再發起一次選舉。服務器A和B分別投本身一票並交換選票信息:此時服務器A發現服務器B的ID比本身目前投票推舉的(服務器A)大,更改選票爲推舉服務器B。此時服務器A票數0票,服務器B票數2票,沒有半數以上結果,選舉沒法完成,服務器A、B狀態保持LOOKING。

三、服務器C啓動,發起一次選舉。此時服務器A和B都會更改選票爲服務器C。這次投票結果:服務器A爲0票,服務器B爲0票,服務器C爲3票。此時服務器C的票數已經超過半數,服務器C當選Leader。服務器A、B更改狀態爲FOLLOWING,服務器C更改狀態爲LEADING。

四、服務器D啓動,發起一次選舉。此時服務器A、B、C已經不是LOOKING狀態,不會更改選票信息。交換選票信息結果:服務器C爲3票,服務器D爲1票。此時服務器D服從多數,更改選票信息爲服務器C,並更改狀態爲FOLLOWING。

五、服務器E啓動,過程同4。

2、ZAB協議

2.1 ZAB協議是什麼

ZAB協議的全稱是Zookeeper Atomic Broadcast(Zookeeper原子廣播)。Zookeeper是經過ZAB協議來保證分佈式事務的最終一致性。ZAB協議是爲分佈式協調服務Zookeeper專門設計的一種支持崩潰恢復的原子廣播協議,是Zookeeper保證數據一致性的核心算法。ZAB借鑑了Paxos算法,但又不像Paxos算法那樣,是一種通用的分佈式一致性算法。它是特別爲Zookeeper設計的支持崩潰恢復的原子廣播協議。

在Zookeeper中主要依賴ZAB協議來實現數據一致性,基於該協議,Zookeeper實現了一種主備模型(即Leader和Follower模型)的系統架構來保證集羣中各個副本之間數據的一致性。這裏的主備系統架構模型,就是指只有一臺客戶端(Leader)負責處理外部的寫事務請求,而後Leader客戶端將數據同步到其餘Follower節點。Zookeeper客戶端會隨機的連接到Zookeeper集羣中的一個節點,若是是讀請求,就直接從當前節點中讀取數據;若是是寫請求,那麼節點就會向Leader提交事務,Leader接收到事務提交,會廣播該事務,只要超過半數節點寫入成功,該事務就會被提交。

ZAB協議的特性:

一、ZAB協議須要確保那些已經在Leader服務器上提交的事務最終被全部的服務器提交。

二、ZAB協議須要確保丟棄那些只在Leader上被提出而沒有被提交的事務。

2.2 ZAB協議的做用

一、當主進程出現異常的時候,整個Zookeeper集羣依舊可以正常工做。

二、使用一個Leader來接收並處理客戶端的事務請求,並採用ZAB的原子廣播協議,將服務器數據的狀態變動以事務proposal(事務提議)的形式廣播到全部的Follower進程上去。

三、保證一個全局的變動序列被順序引用。Zookeeper是一個樹形結構,不少操做都要先檢查才能肯定是否能夠執行,爲了保證這一點,ZAB要保證同一個Leader發起的事務要按順序被請求,同時還要保證只有先前Leader的事務被請求以後,新選舉出來的Leader才能再次發起事務。

2.3 ZAB協議的原理

ZAB協議要求每一個Leader都要經歷三個階段:發現、同步、廣播。

發現階段要求Zookeeper集羣必須選舉出一個Leader,同時Leader會維護一個Follower可用客戶端列表。未來客戶端能夠和這些Follower節點進行通訊。同步階段Leader要負責將自己的數據與Follower完成同步,作到多副本存儲。Follower將隊列中未處理完的請求消費完成後,寫入本地事務日誌中。廣播階段Leader能夠接受客戶端新的事務Proposal請求,將新的Proposal請求廣播給全部的Follower。

ZAB協議定義了事務請求的處理方式:全部的事務請求必須由一個全局惟一的服務器來協調處理,這樣的服務器被叫作Leader服務器。其餘剩餘的服務器則是Follower服務器。Leader服務器負責將一個客戶端事務請求,轉換成一個事務Proposal,並將該Proposal分發給集羣中全部的Follower服務器,也就是向全部 Follower節點發送數據廣播請求。分發以後Leader服務器須要等待全部Follower服務器的反饋,在ZAB協議中,只要超過半數的Follower服務器進行了正確的反饋後,那麼Leader就會再次向全部的Follower服務器發送Commit消息,要求其將上一個事務proposal進行提交。這也就是上文中1.4提到的寫數據流程。

2.4 ZAB協議的工做

當整個集羣啓動過程當中,或者當Leader服務器出現網絡中弄斷、崩潰退出或重啓等異常時,ZAB協議就會進入崩潰恢復模式,選舉產生新的Leader。當選舉產生了新的Leader,同時集羣中有過半的機器與該Leader服務器完成了狀態同步(即數據同步)以後,ZAB協議就會退出崩潰恢復模式,進入消息廣播模式。這時,若是有一臺遵照ZAB協議的服務器加入集羣,由於此時集羣中已經存在一個Leader服務器在廣播消息,那麼該新加入的服務器自動進入恢復模式:找到Leader服務器,而且完成數據同步。同步完成後,做爲新的Follower一塊兒參與到消息廣播流程中。

當Leader出現崩潰退出或者機器重啓,亦或是集羣中不存在超過半數的服務器與Leader保存正常通訊,ZAB協議就會再一次進入崩潰恢復,發起新一輪Leader選舉並實現數據同步。同步完成後又會進入消息廣播模式,接收事務請求。在整個消息廣播中,Leader會將每個事務請求轉換成對應的proposal來進行廣播,而且在廣播事務Proposal以前,Leader服務器會首先爲這個事務Proposal分配一個全局單遞增的惟一ID,稱之爲事務ID(即zxid),因爲ZAB協議須要保證每個消息的嚴格的順序關係,所以必須將每個proposal按照其zxid的前後順序進行排序和處理。

2.4.1 消息廣播

消息廣播的步驟以下:

一、客戶端發起一個寫操做請求。

二、Leader服務器將客戶端的請求轉化爲事務Proposal提案,同時爲每一個Proposal分配一個全局的ID,即zxid。

三、Leader服務器爲每一個Follower服務器分配一個單獨的隊列,而後將須要廣播的Proposal依次放到隊列中去,而且根據FIFO策略進行消息發送。

四、Follower接收到Proposal後,會首先將其以事務日誌的方式寫入本地磁盤中,寫入成功後向Leader反饋一個Ack響應消息。

五、Leader接收到超過半數以上Follower的Ack響應消息後,即認爲消息發送成功,能夠發送commit消息。

六、Leader向全部Follower廣播commit消息,同時自身也會完成事務提交。Follower接收到commit消息後,會將上一條事務提交。

Zookeeper採用ZAB協議的核心,就是隻要有一臺服務器提交了Proposal,就要確保全部的服務器最終都能正確提交Proposal。Leader服務器與每個Follower服務器之間都維護了一個單獨的FIFO消息隊列進行收發消息,使用隊列消息能夠作到異步解耦。Leader和Follower之間只須要往隊列中發消息便可。若是使用同步的方式會引發阻塞,性能要降低不少。

2.4.2 崩潰恢復

一旦Leader服務器出現崩潰或者因爲網絡緣由致使Leader服務器失去了與過半Follower的聯繫,那麼就會進入崩潰恢復模式。在ZAB協議中,爲了保證程序的正確運行,整個恢復過程結束後須要選舉出一個新的Leader服務器。

ZAB協議崩潰恢復要求知足兩個要求:一、確保已經被Leader提交的Proposal必須最終被全部的Follower服務器提交。二、確保丟棄已經被Leader提出的可是沒有被提交的Proposal。根據上述要求ZAB協議須要保證選舉出來的Leader知足如下條件:一、新選舉出來的Leader不能包含未提交的Proposal。即新選舉的Leader必須都是已經提交了Proposal的Follower服務器節點。二、新選舉的Leader節點中含有最大的zxid。

2.5 ZAB數據同步

一、完成Leader選舉後新的Leader具備最高的zxid,在正式開始工做以前(接收事務請求,而後提出新的Proposal),Leader服務器會首先確認事務日誌中的全部的Proposal是否已經被集羣中過半的服務器Commit。

二、Leader服務器須要確保全部的Follower服務器可以接收到每一條事務的Proposal,而且能將全部已經提交的事務Proposal應用到內存數據中。等到Follower將全部還沒有同步的事務Proposal都從Leader服務器上同步過來而且應用到內存數據中之後,Leader纔會把該Follower加入到真正可用的Follower列表中。

在ZAB的事務編號zxid設計中,zxid是一個64位的數字。其中低32位能夠當作一個簡單的單增計數器,針對客戶端每個事務請求,Leader在產生新的Proposal事務時,都會對該計數器加1。而高32位則表明了Leader週期的epoch編號。epoch編號能夠理解爲當前集羣所處的年代或者週期。每次Leader變動以後都會在epoch的基礎上加1,這樣舊的Leader崩潰恢復以後,其餘Follower也不會聽它的,由於Follower只服從epoch最高的Leader命令。每當選舉產生一個新的Leader,就會從這個Leader服務器上取出本地事務日誌中最大編號Proposal的zxid,並從zxid中解析獲得對應的epoch編號,而後再對其加1,以後該編號就做爲新的epoch值,並將低32位數字歸零,由0開始從新生成zxid。ZAB協議經過epoch編號來區分Leader變化週期,可以有效避免不一樣的Leader錯誤的使用了相同的zxid編號提出了不同的Proposal的異常狀況。基於以上策略當一個包含了上一個Leader週期中還沒有提交過的事務Proposal的服務器啓動時,當這臺機器加入集羣中,以Follower角色連上Leader服務器後,Leader服務器會根據本身服務器上最後提交的Proposal來和Follower服務器的Proposal進行比對,比對的結果確定是Leader要求Follower進行一個回退操做,回退到一個確實已經被集羣中過半機器Commit的最新Proposal。

 

到這本文基本上接近尾聲了,這篇文章理論描述居多,可能會比較枯燥,大家有什麼問題,歡迎留言,讓我看看大家都有哪些問題~

相關文章
相關標籤/搜索