Zookeeper 選舉機制和腦裂問題
之前剛接觸的時候對這兩個概念有所了解,因為用不到,隔一段時間就忘了。網上的解答又魚龍混雜,由於各人理解不同,工作/學習環境不同,結果良莠不齊。每次搜索回憶都需要很長時間。在此特地將我個人的理解記錄下來。
如果文章內容有問題,歡迎評論或與我進行討論(請注明原因):
mail: wgh0807@qq.com
微信: hello-wgh0807
qq: 490536401
zookeeper選舉
-
zookeeper 集群中包含的角色:
-
leader,領導人,負責投票發起和決議;更新系統狀態;分配用戶請求到跟隨者;不實際處理業務。在集群中也被稱為master。
-
follower,跟隨者,接收客戶請求,想客戶返回結果,在集群中也被稱為slave。選舉時參與投票。
-
observe,觀察者,將請求轉發給leader,不參與投票。
tip: 只要有leader 存在,就不進行選舉
-
-
核心:ZAB (Zookeeper Atomic Broadcast, zookeeper原子廣播,用於保證server同步)
ZAB的兩種工作模式:
- 恢復模式(選主)
- 廣播模式(同步)
-
zookeeper集群的配置:提前在其配置文件中配置集群中機器的ip和端口 (這點很重要,不是自主發現,未配置的zk無法混入集群中)
-
選舉前提:
- 半數可用機制(半數以上個zk服務器可用才執行選舉,不然無法滿足條件3)
- no leader(無領導情況下才能選舉)
- 半數選舉機制(某一個leader必須獲取半數以上張選票才能成為leader。用於防止腦裂問題)
-
選舉流程(以五台服務器為例):
Note: 在注冊時,每台server會獲得一個ID(配置文件可以指定ID)。除人工指定外,ID是遞增的 。在無leader情況下,ID較低的zk服從ID較高的zk。以下zk服務器的ID等於其編號。
Note 2: Leader不負責實際處理用戶請求。故單台ZK Server不會成為leader。
- Server 1啟動,先投自己,獲得的票數是1/5,未超過半數,選舉無效。
- Server 2啟動,先投自己,Server 1 跟從Server 2 投票給2,Server 2獲得票數為2/5,未超過半數,選舉無效。
- Server 3啟動,先投自己,Server 1 和 2 跟從Server 3 投票給 3 ,Server 3 獲得票數為 3/5,超過半數,選舉生效,server 3 成為集群中的leader。
- Server 4啟動,此時已經不滿足選舉條件,無選舉行為。
- Server 5啟動,同樣不滿足選舉條件,無選舉行為。
-
時間軸如下(丑是丑了點,將就看吧):

-
結果:此時Server 3 成為集群的leader,其他的server成為follower。
腦裂問題
腦裂,即有兩個大腦。在集群中表現為兩個leader(master)。容易導致同步問題、資源搶占和死鎖問題。
產生環境事例和解決方案:
tip:此處舉例使用了六台服務器,會發現不符合推薦的奇數個服務器。因為6台服務器和7台服務器需要經過的選舉次數相同(都是至少獲得4票),但是處理能力卻不如7台服務器。故推薦選擇奇數個服務器。
- 網絡環境變化(常見):假設之前Server 1 為leader,其他的為slave,若沒有半數選舉機制,遇到網線(或心跳線)斷開的情況,則網絡環境B會選舉一台新的leader。當網線/心跳線恢復后,這一集群合二為一后,將有兩個leader。

解決方案:引入半數選舉機制,必須獲得半數以上票數選舉生效,可以有效避免這種情況下的腦裂問題。
- 在上圖網絡環境中,假設server 1 是leader,某一時刻突然宕機,其他機器開始選舉leader。但是server 1 宕機恢復了,則出現了新選舉的leader和舊leader 並存的情況。
解決方案:先入為主(具體名字我忘記了,這里是按照我的印象完成的,若有問題請評論或聯系我)原則,若舊leader恢復在選舉完成之前,則停止選舉,使用舊leader。若恢復時選舉已經完成,則采用新的leader。
參考資料:
zookeeper的選舉機制 - HandsomeEric - cnblogs
《分布式數據庫架構與企業實踐-基於Mycat中間件》周繼峰,馮鑽優,陳勝尊,左越宗著
部分資料源於我的leader - @李詩明
如有問題,歡迎評論或聯系我討論。
