天天看點

ZooKeeper系列:ZAB協定一、ZAB協定的核心二、基本模式

一、ZAB協定的核心

    所有事務請求必須由一個全局唯一的伺服器來協調處理,這樣的伺服器被稱為 Leader 伺服器,而餘下的其他伺服器則成為 Follower 伺服器。 Leader伺服器負責将一個用戶端事務請求轉換成一個事務Proposal(提議),并将該Proposal分發給叢集中所有的Follower 伺服器。之後Leader伺服器需要等待所有Follower伺服器的回報,一旦超過半數的Follower伺服器進行了正确的回報後,那麼Leader就會再次向其他所有的伺服器分發Commit消息,要求其将前一個Proposal進行送出。

    這裡需要注意的是,如果是叢集中的非Leader伺服器收到了用戶端的事務請求,那麼會将這個請求轉發給Leader伺服器。

二、基本模式

    ZAB協定主要包含兩個基本模式:消息廣播和崩潰恢複。

1、消息廣播

    當叢集中過半伺服器和Leader完成了狀态同步後,ZAB協定就進入了消息廣播模式。

    ZAB協定通過原子廣播協定來實作消息的廣播過程。當Leader伺服器接收到用戶端的事務請求時,會為其生成對應的事務Proposal,并将Proposal發送給叢集中的其他機器。Follower收到Proposal後有兩個選擇:同意事務,或者抛棄Leader伺服器。當Leader伺服器收集到超過一半Follower的投票時,就會想所有的機器發送Commit指令,要求送出事務。

    當然,這裡有一些問題。如果Leader在發送完全部Commit指令前就發生了故障,這時候可能會導緻這次的資料更新産生不一緻的問題,因為可能有些伺服器上送出了事務,而有些伺服器沒收到事務送出的請求。zk通過使用崩潰恢複機制來解決這個問題。

    另外,消息廣播使用TCP協定進行通信。TCP協定FIFO的特性可以保證消息廣播過程中消息接收預發送的順序性。

    對于廣播事務Proposal,Leader伺服器會為每個事務請求都配置設定一個全局唯一、且單調遞增的事務id(ZXID)。

    消息廣播過程中,Leader 伺服器會為每一個Follower伺服器都各自配置設定一個單獨的隊列,然後将需要廣播的事務Proposal依次放入這些隊列中,根據FIFO政策進行消息發送。每一個 FolIower伺服器在接收到這個事務Proposal之後,都會首先将其以事務日志的形式寫入到本地磁盤中去,并且在成功寫入後回報給Leader伺服器一個Ack響應。當Leader伺服器接收到超過半數Follower的Ack響應後,就會廣播一個Commit消息給所有的Follower伺服器以通知其進行事務送出,同時Leader自身也會完成對事務的送出,而每一個Follower伺服器在接收到Commit消息後,也會完成對事務的送出。

2、崩潰恢複

    在叢集啟動,或者Leader伺服器出現網絡中斷、崩潰退出、重新開機等異常情況,導緻Leader伺服器不能和過半伺服器取得聯系的時候,ZAB協定會進入恢複模式,并選舉産生新的Leader伺服器。新Leader産生并且叢集中過半的機器完成狀态同步後,ZAB協定退出恢複模式。其中,狀态同步就是資料同步。

    在消息廣播狀态,如果一台新的伺服器加入叢集,或者失聯的機器恢複連接配接後,該機器會自動進入恢複模式,去尋找Leader伺服器并進行狀态同步,然後退出恢複模式進入消息廣播的狀态。

    崩潰恢複的核心的高效可靠的Leader選舉算法:一方面,要讓Leader伺服器自身快速認識到自身已經成為新的Leader;另一方面,還要讓叢集中的其他機器快速感覺到新的Leader伺服器。

1、基本特性

    1)ZAB協定確定在Leader伺服器上送出的事務,最終要被全部伺服器都送出;

    2)ZAB協定確定丢棄隻在Leader伺服器上被送出的事務。

    這兩條基本特性的保證,ZAB協定是通過ZXID(事務編号)來進行保證的。ZAB的Leader選舉算法保證,新選舉出來的Leader伺服器擁有最高的ZXID,這樣,這個新的Leader伺服器一定擁有所有已送出的事務。同時,這也能省去新Leader檢查事務送出和丢棄的過程,隻需要要求其他伺服器同步自己的狀态即可。

2、資料同步

    Leader選舉完成後,首先會确認資料同步是否完成。資料同步完成的标志,是事務日志中所有的事務,都被一半以上的Follower送出了。

    ZXID是一個64位的數字。低32位是針對用戶端的每一個事務請求的編号,Leader伺服器每産生新的事務Proposal,都會對該計數器加1;高32位則代表了Leader周期epoch的編号,每當選舉産生新的Leader,就會将Leader伺服器本地日志中最大事務的ZXID的epoch加1,并将低32位置0來生成新的ZXID。

    基于上述政策,當一個新機器加入叢集,或者崩潰叢集恢複連接配接,如果叢集中包含以前周期中的未送出事務,這些事務就會被丢棄;同時,周期落後的機器的ZXID肯定比周期更先進的機器要小,也就不會在選舉中成為新的leader。