ZooKeeper集群解析。
作者:IT王小二
博客:https://itwxe.com
這篇文章中來介紹一下 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 協議核心是在整個 zookeeper 集群中只有一個節點既 leader 將所有客戶端的寫操作轉化為事務(提議 proposal),leader 節點再數據寫完之后,將向所有的 follower 節點發送數據廣播請求(數據復制)。
- 等所有的 follower 節點的反饋。
- 在 zab 協議中,只要超過半數 follower 節點反饋 ok,leader 節點會向所有 follower 服務器發送 commit 消息,既將 leader 節點上的數據同步到 follower 節點之上。
2. 崩潰恢復
什么時候會發生崩潰恢復?
- 當服務器啟動時
- 當leader 服務器出現網絡中斷,崩潰或者重啟的情況
- 當集群中已經不存在過半的服務器與Leader服務器保持正常通信
崩潰恢復的過程
- 每個 Server 會發出一個投票,第一次都是投自己。投票信息:(myid,ZXID)
- 收集來自各個服務器的投票
- 處理投票並重新投票,處理邏輯:優先比較 ZXID,然后比較 myid
- 統計投票,只要超過半數的機器接收到同樣的投票信息,就可以確定 leader
- 改變服務器狀態
為什么要有限比較ZXID呢?
因為ZXID為事務id,值越大,證明它的數據最新。
在這個選舉過程中每個 Server 有三種狀態:
- LOOKING:當前Server不知道leader是誰,正在搜尋
- LEADING:當前Server即為選舉出來的leader
- FOLLOWING:leader已經選舉出來,當前Server與之同步
兩種特殊情況
- 已經被處理的事務請求(proposal)不能丟(commit的)。
- 沒被處理的事務請求(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 反饋。
具體步驟如下:
- 客戶端發起一個寫操作請求
- Leader 服務器將客戶端的 request 請求轉化為事物 proposql 提案,同時為每個 proposal 分配一個全局唯一的 ID,即 ZXID
- leader 服務器與每個 follower 之間都有一個隊列,leader 將消息發送到該隊列
- follower 機器從隊列中取出消息處理完(寫入本地事物日志中)畢后,向 leader 服務器發送 ACK 確認
- leader 服務器收到半數以上的 follower 的 ACK 后,即認為可以發送 commit
- leader 向所有的 follower 服務器發送 commit 消息
都讀到這里了,來個 點贊、評論、關注、收藏 吧!