天天看點

ZooKeeper ZAB協定:崩潰恢複、消息廣播ZAB協定

文章目錄

  • ZAB協定
    • 消息廣播
    • 崩潰恢複

ZAB協定

ZAB(ZooKeeper Atomic Broadcast 原子廣播) 協定是為分布式協調服務ZooKeeper專門設計的一種支援崩潰恢複的原子廣播協定。 在ZooKeeper中,主要依賴ZAB協定來實作分布式資料一緻性,基于該協定,ZooKeeper實作了一種主備模式的系統架構來保持叢集中各個副本之間的資料一緻性。

ZAB協定包括了兩種基本的模式,分别是崩潰恢複和消息廣播。

消息廣播

為了保證叢集中存在過半的機器能夠和Leader伺服器的資料狀态保持一緻,ZAB協定中引入了消息廣播模式。

在上面我們提到了,ZooKeeper叢集中隻有Leader伺服器能夠執行寫操作,為了保證叢集的資料一緻性,我們需要将Leader節點更新的資料同步到Follower與Observer伺服器中,是以當Leader伺服器接收到用戶端發送的寫請求後,會自動生成對應的提案并發起一輪消息廣播。

消息廣播的執行流程如下:

  1. 接受到用戶端發送的事務請求,Leader伺服器為其生成對應的事務提議。
  2. Leader為每一個Follower和Observer都準備了一個FIFO的隊列,并把提議發送到隊列上。
  3. 當Follower接收到事務提議後,都會先将其以事務日志的形式寫入本地磁盤中,然後再寫入成功後回報給Leader伺服器一個ACK。
  4. 當Leader接收到半數以上Follower節點的ACK,它就會認為大部分節點都同意議題,準備開始送出。
  5. Leader向所有節點發送送出事務的Commit請求,完成事務。
ZooKeeper ZAB協定:崩潰恢複、消息廣播ZAB協定

消息廣播流程

為了防止因為網絡等原因導緻的Follower、Observer節點處理請求的順序不同而導緻的資料不一緻問題,保證消息廣播過程中消息接收與發送的順序性,消息廣播中引入了**FIFO隊列**和**事務ID**來解決這個問題。

  • 在消息廣播的過程中,Leader伺服器會為每一個Follower、Observer伺服器都各自配置設定一個單獨的隊列,然後将需要廣播的事務提議放到這些隊列中,并根據FIFO政策進行消息發送。由于ZAB由于協定是通過TCP協定來進行網絡通信的,這樣不僅保證了消息的發送順序性,也保證了接受順序性。
  • 在廣播事務提議之前,Leader伺服器會先給這個提議配置設定一個全局單調遞增的唯一事務ID(ZXID)。為了保證每一個消息嚴格的因果關系,必須将每一個事務提議按照其ZXID的先後順序來進行排序與處理。

如果你了解過二階段送出(2PC)協定,你會發現其實消息廣播的過程實際上就是一個簡化版本的二階段送出過程,他将二階段送出中的中斷邏輯删除,Leader伺服器不需要等待叢集中的全部Follower伺服器都響應回報,隻需要得到過半Follower的ACK就開始執行事務的送出。這種簡化版的2PC雖然提高了效率,但是無法處理Leader伺服器崩潰退出而導緻的資料不一緻問題,是以ZooKeeper中又添加了崩潰恢複模式來解決這個問題。

崩潰恢複

當Leader伺服器出現崩潰退出或機器重新開機,亦或是叢集中不存在半數以上的伺服器與Leader伺服器保持正常通信時,在重新開始新的一輪原子廣播事務操作之前,此時所有節點都會使用崩潰恢複協定來使彼此達到一個一緻的狀态。

崩潰恢複過程需要確定那些已經在Leader伺服器上送出的事務最終被所有的事務送出。

假設一個事務中Leader伺服器(server2)上被送出了,并且已經得到了過半Follower伺服器的ACK回報,但是在它将Commit消息發送給所有的Follower機器之前,Leader伺服器就挂掉了,如下圖:

ZooKeeper ZAB協定:崩潰恢複、消息廣播ZAB協定

確定那些已經在Leader伺服器上送出的事務最終被所有的事務送出

從上圖可以看到,部分的節點收到了commit請求并進行了送出,而有一部分Leader還沒來得及發送就已經崩潰了。針對這種情況,崩潰恢複必須要確定該事務最終能夠在所有的伺服器上都被送出成功,否則将會出現資料不一緻的情況。是以在重新選舉的時候,必定會選取ZXID最大的節點來確定其保留了最新的事件。

崩潰恢複過程需要確定丢棄那些隻在Leader伺服器上被提出的事務。

如果Leader伺服器在送出了一個事務之後,還沒來得及廣播發送commit就已經崩潰推出了,進而導緻叢集中的其他伺服器都沒有收到這個事務提議。當原先的Leader節點故障恢複後,再次以Follower的角色加入叢集後,此時就因為隻有它完成了事務送出,而産生了資料不一緻的情況,如下圖:

ZooKeeper ZAB協定:崩潰恢複、消息廣播ZAB協定

確定丢棄那些隻在Leader伺服器上被提出的事務

針對這種情況,我們需要讓server2在故障恢複後能夠丢棄這些隻在它這個節點上提出的事務,來確定資料一緻。

為了能夠滿足上述的兩個要求,是以ZooKeeper讓Leader選舉算法保證新選舉出來的Leader伺服器擁有叢集中所有機器最高的事務編号(ZXID最大),那麼這就肯定能夠保證新選舉出來的Leader一定具有所有已經送出的提案,此時新的Leader就會将事務日志中尚未送出的消息同步到各個伺服器中。

繼續閱讀