淺談Zookeeper【二】ZAB協議原理

ZAB協議介紹

ZAB協議(Zookeeper Atomic Broadcast)時Zk中保證數據一致性的重要協議,是基於Paxos算法單獨爲Zk實現的協議。

ZAB協議是一種支持崩潰恢復和原子廣播的協議,基於zab協議,zk實現了一種主備模式的系統架構,由單一的主進程來處理客戶端的請求,並且爲每個請求分配一個全局唯一單調遞增的事務ID(zxid),然後由主進程將數據廣播給副本進程上去。所以說zk是一個保證順序一致性的服務。

所有事務請求必須由一個全局唯一的服務器來協調處理,這樣的服務器稱之爲Leader服務器,而餘下的服務器稱之爲Follower服務器。Leader服務器負責將一個客戶端事務請求轉化爲一個事務Proposal(提議),並將該事務提議分發給Follower,之後Leader等待Follower的ACK反饋,一但超過半數的Follower正確反饋,那麼Leader將向所有Follower發送一個commit消息,要求Follower把前一個事務提議進行提交。

Zab協議的過程如下圖所示:
zk服務器由三節點構成,1主2從,客戶端所有的事務請求由Leader進行處理,並且通過廣播發送給Follower副本。
ZAB流程

ZAB協議基本特性

(1)高可用:由於採用主備模型,可以保證當Leader節點掛機或者網絡分區後,集羣依然工作對外提供服務。(當集羣中超過半數節點存活,整個集羣可用)

(2)數據一致性:一個事務請求只能由Leader節點處理,Leader節點將事務請求廣播給副本節點。保證如果一個事務被提交成功,那麼所有節點都應該被處理成功。

1、Zab協議確保在Leader服務器提交的事務最終被所有服務器提交
2、Zab協議需要確保丟棄那些只在 Leader 上被提出而沒有被提交的事務。

(3)保證事務順序:由於zk是樹形目錄結構,創建子節點時需要存在父節點,Zab要保證同一個Leader發起的事務按順序執行,同時還要保證只有先前Leader的事務被執行之後,新的Leader才能再次發起事務。

ZAB協議核心

ZAB協議基本模式

ZAB協議有兩種基本模式,分別爲崩潰恢復和消息廣播,接下來通過一個流程介紹兩種模式分別是什麼。

  1. 服務器啓動: 當服務器第一次啓動時,整個集羣服務沒有Leader節點,則此時進入恢復模式並選舉一個Leader節點,選舉成功後其他節點與Leader保持狀態同步,當過半的節點與Leader狀態同步後則退出恢復模式,進入消息廣播模式。
  2. 服務器運行: 服務運行期間爲消息廣播模式階段,客戶端的每個事務提議請求(proposal)由Leader節點生成一個zxid轉化爲事務請求,然後通過消息廣播發給Follower節點,當超過半數的Follower節點正確響應後,提交該事務。
  3. 新節點加入: 當一個新的zk服務節點加入時,如果此時集羣中存在Leader節點,那麼將自動切換爲數據恢復模式,與Leader節點進行數據同步,然後參與到消息廣播中去。
  4. Leader節點宕機、網絡分區、超過半數節點狀態不同步: 當出現上述中的情況時,那麼整個ZK服務停止,由廣播模式切換到崩潰恢復模式,然後經過選舉、同步一系列操作後,再次進入新一輪消息廣播模式中。

崩潰恢復與消息廣播

ZXID:爲每一個事務請求分配的單調遞增唯一ID標識,其中低32位標識Leader任期的epoch編號,高32位標識該任期內的事務id。每次Leader選舉epoch都會增加,事務id歸零。

消息廣播:
ZAB協議消息廣播,是類似於一個兩階段提交協議實現的,整體分爲三個步驟。
1、首先Leader收到客戶端的數據更新請求後,轉化爲一個事務提議,然後向Follower節點發送數據變更請求。
2、當Follower接受到事務請求後,將事務以日誌的形式寫入本地磁盤,並且返回給Leader一個ACK響應。
3、當Leader收到超過半數(半數中包括Leader)的正確ACK響應後,發送該事務的提交請求commit給Follower。
消息廣播
其實在實際的通信過程中,Leader會爲每個事務請求分配一個全局單調遞增的ZXID,因此每個事務按照ZXID的順序進行排序處理。Leader還會爲每個Follower創建一個FIFO的隊列,用來存放Leader的請求,這樣可以保證每個事務的順序執行,ZK不要求每個Follower執行完畢,只需要保證寫入FIFO隊列中即可。

完整廣播

崩潰恢復:
當Leader節點崩潰或下線時,還可能由於網絡分區導致Leader失去與超過一半節點的連接時,此時進入到崩潰恢復模式。

ZAB協議爲了保證程序的正確運行,此時需要通過Leader選舉算法選舉出一個新的Leader節點,同時能夠讓其他所有節點快速感知到新選舉的Leader節點。

ZAB協議還要確保,無論出現任何問題都需要保證數據一致性,在崩潰恢復的過程中,可能會出現兩種情況出現數據不一致。
P1:代表Proposal1事務的請求
C1:代表Proposal1事務的提交Commit

情況一:
當Leader發送C2的時候崩潰退出,那麼ZAB協議需要保證P2最終能夠在所有服務器上執行,否則會出現不一致。
在這裏插入圖片描述
情況2:
如果在崩潰恢復過程中,需要丟棄一個Proposal提案時,那麼確保在崩潰恢復結算時跳過需要被丟棄的提案。

如下圖所示,Proposal3 只有在Leader上提出後便發生崩潰,那麼需要確保在集羣恢復後,保證Proposal3被跳過,不會執行。
在這裏插入圖片描述
結合上面的案例,ZAB協議決定Leader選舉算法必須滿足已上兩個條件:1、確保提交被Leader提交的事務;2、確保丟棄已經被跳過的事務;
在Leader選舉階段,通過選取具有最大事務編號zxid的爲Leader節點,這樣保證新的Leader具有最全的數據,並且Leader服務器需要確保每一個Proposal都被半數以上機器提交。

當Leader選舉完畢後,則崩潰恢復進入到數據恢復階段。當其他服務器感知到Leader服務器出現後,則從Leader服務器同步數據,

完成 Leader 選舉後(新的 Leader 具有最大的zxid),在開始對外提供服務之前,Leader 服務器會首先確認事務日誌中的所有的 Proposal 是否已經被集羣中過半的服務器 Commit。

Leader 服務器需要確保所有的 Follower 服務器能夠接收到每一條事務的 Proposal ,並且能將所有已經提交的事務 Proposal 應用到內存數據中。等到 Follower 將所有尚未同步的事務 Proposal 都從 Leader 服務器上同步過啦並且應用到內存數據中以後,Leader 纔會把該 Follower 加入到真正可用的 Follower 列表中。

等到Follower服務器保持與Leader同步後,Leader就會將該機器加入到可用Follower列表當中,列表中超過過半機器後,則進入消息廣播模式,開始對外提供服務。

ZAB協議內部原理

從算法角度描述,ZAB協議主要分爲三個階段,分別爲發現、同步、廣播,每一個進程都會循環執行三個階段,一個循環稱之爲一個主進程週期。

階段一 發現:
就是Leader選舉階段,該階段選擇具有最大zxid的服務器,並且會從過半Follower中選擇最大的epoch然後+1 生成新的epoch發送給follower。

階段二 同步:
該階段,Leader將自己的epoch和事務集合發送給Follower,Follower判斷自己的epoch是否和Leader一致,如果不一致說明自己還在之前的輪次,不參與同步,如果一致則會執行Leader的事務集合,然後返回給Leader響應。當Leader收到過半Follower的ACK響應後,會再次發送Commit信息。

階段三 廣播:
在完成同步階段後,此時可以對外提供服務了,並且接受客戶端新的事務請求,進入到廣播流程。

小結:
ZK服務運行期間,會不斷進行上述三個階段的循環,每一次循環爲一個週期。

總結

本文詳細的描述了ZAB協議的原理和服務的運行階段,以及模式的轉換過程。但是沒有詳細說明Leader的選舉算法,在下一篇文章中講述。

ZK運行期間,每個進程都會處於三種狀態之一:
LOOKING:Leader選舉階段
FOLLOWING:Follower與Leader保持同步狀態
LEADING:Leader做爲主進程領導狀態

參考文獻:
1、從paxos到Zookeeper分佈式一致性原理與實踐
2、https://www.jianshu.com/p/2bceacd60b8a

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章