ZooKeeper 04 – ZooKeeper 集群的節點為什麼必須是奇數個

首發於 2018-12-08,修改於 2021-12-06。

1 – 關於節點個數的說明

ZooKeeper 的單機服務 (也就是單節點,或著單進程) 雖然便於開發與測試,但並不適合在生產環境使用 —— 生產環境中為了服務的高可用以及容錯性,建議使用 ZooKeeper 集群模式.

ZooKeeper 集群中,建議部署奇數個 ZooKeeper節點(或進程) —— 大多數情況下,3個節點就足夠了。

節點個數並不是越多越好 —— 節點越多,節點間通訊所需的時間就會越久,選舉 Leader 時需要的時間也會越久。

2 – ZooKeeper 集群的容錯數

ZooKeeper 集群中,在保證集群可用的前提下,最多允許掛掉的節點個數,即為 ZooKeeper 集群的容錯數,也叫集群的容忍度。

為了集群中 Leader 節點的選舉,允許掛掉的節點個數 < 剩餘的存活節點個數 —— 剩餘的存活節點個數必須大於n/2,n為總節點個數。

2n 和 2n-1(n>1) 個節點的集群的容錯數都是 n-1。比如:

  • 5個節點中,最多允許掛掉2個,因為剩餘的3個節點大於5/2;
  • 6個節點中,最多允許掛掉2個,因為剩餘的4個節點大於6/2。

3 – ZooKeeper 集群可用的標準

集群模式(包括偽集群模式,即在一台伺服器上部署多個 ZooKeeper 進程)下,遵循 「過半存活即可用」 的原則:

(1) 集群中超過一半的節點(或進程)可以正常工作,集群就是對外可以用的。示例:

  • 2個節點的 ZooKeeper 集群:當 leader (主)節點掛掉,還活躍著的 follower(隨從)節點的數量為1,沒有超過集群總數的一半(即2/2=1),所以此時集群就無法對外提供服務 —— 2個節點的集群容錯數為0
  • 3個節點的 ZooKeeper 集群:當 leader (主)節點掛掉,還活躍著的 follower(隨從)節點的數量為2,就能再次選出 leader 對外提供服務 —— 容錯數為1。
  • 同樣的,5個節點的 ZooKeeper 集群最多允許2個主節點掛掉 —— 容錯數為2。

(2) ZooKeeper 寫操作成功的標誌:

leader 節點負責 ZooKeeper 集群的寫操作,它會通知所有 follower 節點執行寫操作,只有收到半數以上 follower 節點的成功回饋,寫操作才算成功.
如果2個節點的 ZooKeeper 集群,就必須2個節點都寫成功,才能算操作成功。

4 – 為什麼不能是偶數個節點

4.1 防止由腦裂造成的集群不可用

關於 ZooKeeper 集群的腦裂,請參看:ZooKeeper集群的腦裂問題 (Split Brain問題)

舉例說明:

(1) 假如:集群有 5 個節點,發生了腦裂,腦裂成了 A、B 兩個小集群:

(a) 小集群 A:1個節點,小集群 B:4個節點,或A、B互換
(b) 小集群 A:2個節點,小集群 B:3個節點,或A、B互換

上面兩種情況下,A、B 中總會有一個小集群滿足 可用節點數量 > 總節點數量/2 ,所以集群仍然能選舉出 leader,仍然能對外提供服務。

(2) 假如:集群有4個節點,同樣發生腦裂,腦裂成了 A、B 兩個小集群:

(a) 小集群 A:1個節點,小集群 B:3個節點,或 A、B互換 
(b) 小集群 A:2個節點,小集群 B:2個節點

上述情況 (a) 滿足選舉條件,而情況(b)不滿足,此時集群就徹底不能提供服務了。

(3) 總結:

  • 節點數量為奇數個,只要不出現過半的節點失效,集群就總能對外提供服務;
  • 節點數量是偶數個,如果有一半的節點失效,就可能存在集群可用(腦裂成兩個均等的子集群)。

4.2 奇數個節點更省資源

原則上 ZooKeeper 集群中可以有偶數個節點,但其容錯數並不會提高,反而降低了集群間的通訊效率,也浪費了資源。

—— 即:容錯能力相同時,奇數個節點更節省資源.

4.3 偶數個節點遇到的其他問題

部落客測試過2個和4個節點的 ZooKeeper 集群,基於這個前提總結出下述問題:

(1) 分散式環境下,ZooKeeper 集群容易受到網路、系統調度等因素的影響;

(2) 2個 ZooKeeper 節點的集群中:

  • 如果1個 ZooKeeper 節點掛掉,剩下的1個節點並不能滿足「過半存活」的原則,所以集群將不可用;
  • 2個節點的集群比單機模式更不可靠 —— 2個節點中至少1個節點出錯的概率比單節點出錯的概率大;

(3) 4個節點的 ZooKeeper 集群中,第4個節點不能成功啟動,ZooKeeper 會強制 JVM 拋出如下錯誤:

Error occurred during initialization of VM
Unable to allocate 983040KB bitmaps for parallel garbage collection for the requested 31457280KB heap.
Error: Could not create the Java Virtual Machine.
Error: A fatal exception has occurred. Program will exit.

參考資料

zookeeper節點為什麼是奇數個?

zookeeper集群奇偶數節點問題

Zookeeper集群節點數量為什麼要是奇數個?

版權聲明

作者:瘦風(//healchow.com)

出處:部落格園-瘦風的南牆(//www.cnblogs.com/shoufeng)

感謝閱讀,公眾號 「瘦風的南牆」 ,手機端閱讀更佳,還有其他福利和心得輸出,歡迎掃碼關注🤝

本文版權歸部落客所有,歡迎轉載,但 [必須在頁面明顯位置標明原文鏈接],否則部落客保留追究相關人士法律責任的權利。