1. 程式人生 > >再理解ZAB協議

再理解ZAB協議

ZAB 協議全稱是Zookeeper Atomic Broadcast(Zookeeper 原子廣播協議)。是為分散式協調服務ZooKeeper專門設計的一種支援崩潰恢復的原子廣播協議。ZAB協議的開發設計人員在協議設計之初並沒有要求其具有很好的擴充套件性,最初只是為雅虎公司內部那些高吞吐量、低延遲、健壯、簡單的分散式系統場景設計的。在ZooKeeper的官方文件中也指出,ZAB協議並不像Paxos演算法那樣,是一種通用的分散式一致性演算法,它是一種特別為ZooKeeper設計的崩潰可恢復的原子訊息廣播演算法。

假設現在三臺機器,客戶端發起一個寫操作請求,leader伺服器將客戶端的request請求轉化為事物proposql提案,同時為每個proposal分配一個全域性唯一的ID,即ZXID(這裡用兩位數表示前32位和後32位)。

現在follower1和follower2均收到了p1提案,還沒有收到p2和p3。如果此時leader宕機了。也就是說現在在整個叢集中只有p1提交了,p2和p3還未提交。根據ZAB協議要求ZooKeeper叢集進行崩潰恢復和leader伺服器選舉。假設此時follwer2被選為leader。此時新的leader會繼續傳送p2請求,根據ZAB協議,此時p2請求的ZXID在這裡會變做為10。

ZAB協議崩潰恢復要求滿足如下2個要求: 
確保已經被leader提交的proposal必須最終被所有的follower伺服器提交。 
確保丟棄已經被leader出的但是沒有被提交的proposal

針對這個要求,如果讓Leader選舉演算法能夠保證新選舉出來的Leader伺服器擁有叢集中所有機器最高編號(即ZXID最大)的事務Proposal,那麼就可以保證這個新選舉出來的Leader一定具有所有已經提交的提案。更為重要的是,如果讓具有最高編號事務Proposal的機器來成為Leader,就可以省去Leader伺服器檢查Proposal的提交和丟棄工作的這一步操作了。

如果此時新的leader也宕機了,而之前的leader崩潰恢復了。此時之前的leader中的p2和p3兩個事務請求會被丟棄。已經被提交的直接根據最大的ZXID同步資料即可。

下面來看ZAB協議是如何處理那些需要被丟棄的事務Proposal的。在ZAB協議的事務編號ZXID設計中,ZXID是一個64位的
數字,其中低32位可以看作是一個簡單的單調遞增的計數器,針對客戶端的每一個事務請求,Leader伺服器在產生一個新的事務Proposal的時候,都會對該計數器進行加1操作;而高32位則代表了Leader週期epoch的編號,每當選舉產生一個新的 Leader伺服器,就會從這個Leader伺服器上取出其本地日誌中最大事務Proposal的ZXID,並從該ZXID中解析出對應的epoch值,然後再對其進行加1操作,之後就會以此編號作為新的epoch,並將低32位置0來開始生成新的ZXIDo ZAB協議中的這一通過epoch編號來區分Leader週期變化的策略,能夠有效地避免不同的Leader伺服器錯誤地使用相同的ZXID編號提出不一樣的事務Proposa!的異常情況,這對於識別在Leader崩潰恢復前後生成的Proposal非常有幫助,大大簡化和提升了資料恢復流程。

基於這樣的策略,當一個包含了上一個Leader週期中尚未提交過的事務Proposal的伺服器啟動時,其肯定無法成為Leader,原因很簡單,因為當前叢集中一定包含一個Quorum集合,該集合中的機器一定包含了更高epoch的事務Proposal,因此這臺機器的事務Proposal肯定不是最高,也就無法成為Leader了。當這臺機器加入到叢集中,以Follower角色連線上Leader伺服器之後,Leader伺服器會根據自己伺服器上最後被提交的Proposal來和Follower伺服器的Proposal進行比對,比對的結果當然是Leader會要求Follower進行一個回退操作—回退到一個確實已經被叢集中過半機器提交的最新的事務Proposal。

ZAB協議可參看: