在使用zookeeper的過程中,我們經常會看到這樣一些說法:
1.zookeeper cluster的節點數目必須是奇數。
2.zookeeper 集群中必須超過半數節點(Majority)可用,整個集群才能對外可用。
這個說法在大多數情況下是正確的。
實際上ZooKeeper提供了幾種方式來認定整個集群是否可用,Majority只是其中的一種。
(http://zookeeper.apache.org/doc/r3.3.5/zookeeperInternals.html)
1. Majority Quorums
2. Weight
3. Hierarchy of groups
所謂整個集群是否可用,隱含的一個意思就是整個集群還能夠選舉出一個”Leader”。
ZooKeeper默認設置的是采用Majority Qunroms的方式來支持Leader選舉。在ZooKeeper中Quorums有2個作用:
1. 集群中最少的節點數用來選舉Leader保證集群可用
2. 通知客戶端數據已經安全保存前集群中最少數量的節點數已經保存了該數據。一旦這些節點保存了該數據,客戶端將被通知已經安全保存了,可以繼續其他任務。而集群中剩余的節點將會最終也保存了該數據
采用Quoroms投票的方式來選舉Leader主要是為了解決“Split-Brain”問題( http://linux-ha.org/wiki/Split_Brain)。
Split-Brain問題說的是1個集群如果發生了網絡故障,很可能出現1個集群分成了兩部分,而這兩個部分都不知道對方是否存活,不知道到底是網絡問題還是直接機器down了,所以這兩部分都要選舉1個Leader,而一旦兩部分都選出了Leader, 並且網絡又恢復了,那么就會出現兩個Brain的情況,整個集群的行為不一致了。
所以集群要防止出現Split-Brain的問題出現,Quoroms是一種方式,即只有集群中超過半數節點投票才能選舉出Leader。
這樣的方式可以確保leader的唯一性,要么選出唯一的一個leader,要么選舉失敗.
ZooKeeper默認采用了這種方式。更廣義地解決Split-Brain的問題,一般有3種方式:
1. Quorums
2. 采用Redundant communications,冗余通信的方式,集群中采用多種通信方式,防止一種通信方式失效導致集群中的節點無法通信。
3. Fencing, 共享資源的方式,比如能看到共享資源就表示在集群中,能夠獲得共享資源的鎖的就是Leader,看不到共享資源的,就不在集群中
理解了Quorums就不難理解為什么集群中的節點數一般配置為奇數。節點數配置成奇數的集群的容忍度更高。
比如3個節點的集群,Quorums = 2, 也就是說集群可以容忍1個節點失效,這時候還能選舉出1個lead,集群還可用
比如4個節點的集群,它的Quorums = 3,Quorums要超過3,相當於集群的容忍度還是1,如果2個節點失效,那么整個集群還是無效的
所以4個節點的集群的容忍度 = 3個節點的集群的容忍度,但是4個節點的集群多了1個節點,相當於浪費了資源。
更極端的例子是100個節點的集群,如果網絡問題導致分為兩個部分,50個節點和50個節點,這樣整個集群還是不可用的,因為按照Quorums的方式必須51個節點才能保證選出1個Leader。這時候可以采用Weight加權的方式,有些節點的權值高,有些節點的權值低,最后計算權值,只要權值過半,也能選出1個Leader