Zookeeper集羣的崩潰恢復

Zookeeper可以幫我們實現服務的註冊與發現。然而,現在有一個問題是,如果只採用一個Zookeeper服務器,那麼當這個服務器宕機時,意味着整個分佈式服務無法正常工作。爲了解決這一問題,就需要Zookeeper集羣。

然而,在使用Zookeeper集羣時,也存在着一個問題,即集羣中數據一致性的維護。
在這裏插入圖片描述
如上圖所示,Zookeeper集羣是一主多從結構。

  1. 在更新數據時,首先更新到主服務節點,再更新到從服務節點;
  2. 在讀數據時,直接讀取任意從服務節點;
  3. 爲了保證從節點的數據一致性,Zookeeper採用ZAB協議,類似於一致性算法Paxos和Raft。

ZAB解決了集羣崩潰恢復主從數據同步兩個問題。

1. 集羣崩潰恢復

服務節點共有三種狀態:

  1. Looking:選舉狀態;
  2. Following:從服務節點狀態;
  3. Leading:主服務節點狀態。

選舉過程

當主服務節點宕機時,從從服務節點中選舉主服務節點。

  1. 集羣中的服務節點各自向其他節點發起投票,投票當中包含自己的服務器ID和最大ZXID(自增事務ID);

  2. 節點會用自身的ZXID和從其他服務節點接收到的ZXID做比較。如果發現其他節點的ZXID比自己的大,也就是數據比自己新,那麼久重新發起投票,投票給目前已知的最大ZXID所屬的服務節點;

  3. 每次投票之後,服務器都會統計投票數量,判斷是否某個服務節點得到半數或以上的投票,如果存在這樣的節點,該節點將成爲準Leader,狀態變爲Leading,其他節點的狀態變爲Following。

發現階段

通過上述選舉階段後,爲了防止網絡等原因而發生的意外的情況,也就是說,可能出現多主節點的情況。這種情況會發生寫寫衝突,爲了避免這種情況,Leader集思廣益,接收所有的Follower發來的各自最新的epoch值,Leader從中選出最大的epoch,並基於此值加1,生成的新的epoch分發給各個Follower。

各個Follower接收到全新的epoch後,返回ACK給Leader,並帶上各自最大的ZXID和歷史事務日誌。Leader選出最大的ZXID,並更新自身的歷史日誌,以保持數據最新。

同步階段

把Leader收到的最新歷史事務日誌同步給集羣中所有的Follower,只有當半數Follower同步成功,這個準Leader才能成爲正式的Leader。

2. 主從數據同步

ZAB的數據寫入涉及到Broadcase階段,即Leader廣播到所有的Follower,其過程如下:
在這裏插入圖片描述

  1. 客戶端發出寫入數據請求給任意的Follower(服務註冊);
  2. Follower把寫入數據請求轉發給Leader(讀寫分離,讀節點不負責寫,只有主節點能夠寫入);
  3. Leader採用兩階段提交的方式,先發送Propose廣播給Follower(先保留提交日誌,後執行更新,類似於事務);
  4. Follower接收到Propose消息,寫入日誌成功後,返回ACK給Leader(開啓事務);
  5. Leader接收到半數以上的ACK消息,返回成功給客戶端,並且廣播Commit請求給Follower(提交事務,可以進行數據持久化)。

數據一致性有三種:強一致性、弱一致性和順序一致性。而Zookeeper屬於順序一致性。

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