ZooKeeper叢集解析

IT王小二發表於2021-06-28

ZooKeeper叢集解析。

這篇文章中來介紹一下 ZooKeeper 相關的叢集角色,還有 ZAB協議,叢集的安裝在 ZooKeeper入門 中有介紹。

一、ZooKeeper叢集中的角色

  • Leader 叢集工作機制中的核心事務請求的唯一排程和處理者,保證叢集事務處理的順序叢集內部個伺服器的排程者(管理 follower,資料同步),為客戶端提供讀和寫的服務,負責投票的發起和決議,更新系統狀態。
  • Follower 叢集工作機制中的跟隨者處理非事務請求,為客戶端提供讀服務,如果是寫服務則轉發給Leader,參與事務請求 proposal 投票參與 leader 選舉投票。
  • Observer 觀察者3.30 以上版本提供,和 follower 功能相同,但不參與任何形式投票處理非事務請求,轉發事務請求給 Leader 提高叢集非事務處理能力,如果版本高於3.30需要配置使用方式:server.0=192.168.182.130:2888:3888:Observer

二、ZooKeeper叢集一致性協議ZAB

ZAB協議的實現借鑑於 Paxos,是為了解決分散式系統的資料一致性問題。

1. 總覽

zookeeper 就是根據 zab 協議建立了主備模型完成叢集的資料同步(保證資料的一致性),前面介紹了叢集的各種角色,這說所說的主備架構模型指的是,在 zookeeper 叢集中,只有一臺 leader(主節點)負責處理外部客戶端的事務請求(寫操作),leader 節點負責將客戶端的寫運算元據同步到所有的 follower 節點中,大概流程如下:

ZAB總覽

  1. zab 協議核心是在整個 zookeeper 叢集中只有一個節點既 leader 將所有客戶端的寫操作轉化為事務(提議 proposal),leader 節點再資料寫完之後,將向所有的 follower 節點傳送資料廣播請求(資料複製)。
  2. 等所有的 follower 節點的反饋。
  3. 在 zab 協議中,只要超過半數 follower 節點反饋 ok,leader 節點會向所有 follower 伺服器傳送 commit 訊息,既將 leader 節點上的資料同步到 follower 節點之上。

ZAB流程細分

2. 崩潰恢復

什麼時候會發生崩潰恢復?

  1. 當伺服器啟動時
  2. 當leader 伺服器出現網路中斷,崩潰或者重啟的情況
  3. 當叢集中已經不存在過半的伺服器與Leader伺服器保持正常通訊

崩潰恢復的過程

  1. 每個 Server 會發出一個投票,第一次都是投自己。投票資訊:(myid,ZXID)
  2. 收集來自各個伺服器的投票
  3. 處理投票並重新投票,處理邏輯:優先比較 ZXID,然後比較 myid
  4. 統計投票,只要超過半數的機器接收到同樣的投票資訊,就可以確定 leader
  5. 改變伺服器狀態

為什麼要有限比較ZXID呢?

因為ZXID為事務id,值越大,證明它的資料最新。

在這個選舉過程中每個 Server 有三種狀態:

  • LOOKING:當前Server不知道leader是誰,正在搜尋
  • LEADING:當前Server即為選舉出來的leader
  • FOLLOWING:leader已經選舉出來,當前Server與之同步

兩種特殊情況

  1. 已經被處理的事務請求(proposal)不能丟(commit的)。
  2. 沒被處理的事務請求(proposal)不能再次出現。

情況一的出現場景:

當 leader 收到合法數量 follower 的 ACK 後,就向各個 follower 廣播 commit 命令,同時也會在本地執行 commit 並向連線的客戶端返回 成功,但是如果在各個 follower 在收到 commit 命令前 leader 就掛了,導致剩下的伺服器並沒有執行都這條訊息。

那麼這種情況要怎麼處理呢?

1、選舉 ZXID 最大的節點作為新的 leader:由於所有提案被 commit 之前必須有合法數量的 follower ACK,即必須有合法數量的伺服器的事務日誌上有該 proposal,因此,ZXID 最大也就是資料最新的節點儲存了所有被 commit 訊息的 proposal 狀態。
2、新的 leader 將自己事務日誌中 proposal 但未 COMMIT 的訊息處理。
3、新的 leader 與 follower 建立先進先出的佇列, 先將自身有而 follower 沒有的 proposal 傳送給 follower,再將這些 proposal 的 COMMIT 命令傳送給 follower,以保證所有的 follower 都儲存了所有的 proposal、所有的 follower 都處理了所有的訊息,通過以上策略,能保證已經被處理的訊息不會丟。

情況二的出現場景

當 leader 接收到訊息請求生成 proposal 後就掛了,其他 follower 並沒有收到此 proposal,因此經過恢復模式重新選了 leader 後,這條訊息是被跳過的,此時,之前掛了的 leader 重新啟動並註冊成了 follower,他保留了被跳過訊息的 proposal 狀態,與整個系統的狀態是不一致的,所以需要將其刪除。

3. 訊息廣播

在 zookeeper 叢集中資料副本的傳遞策略就是採用的廣播模式,Zab 協議中的 leader 等待 follower 的 ack 反饋,只要半數以上的 follower 成功反饋就好,不需要收到全部的 follower 反饋。

具體步驟如下:

  1. 客戶端發起一個寫操作請求
  2. Leader 伺服器將客戶端的 request 請求轉化為事物 proposql 提案,同時為每個 proposal 分配一個全域性唯一的 ID,即 ZXID
  3. leader 伺服器與每個 follower 之間都有一個佇列,leader 將訊息傳送到該佇列
  4. follower 機器從佇列中取出訊息處理完(寫入本地事物日誌中)畢後,向 leader 伺服器傳送 ACK 確認
  5. leader 伺服器收到半數以上的 follower 的 ACK 後,即認為可以傳送 commit
  6. leader 向所有的 follower 伺服器傳送 commit 訊息

都讀到這裡了,來個 點贊、評論、關注、收藏 吧!

文章作者:IT王小二
首發地址:https://www.itwxe.com/posts/2c8e19cc/
版權宣告:文章內容遵循 署名-非商業性使用-禁止演繹 4.0 國際 進行許可,轉載請在文章頁面明顯位置給出作者與原文連結。

相關文章