1. 伺服器啟動時期的Leader選舉
若進行Leader選舉,則至少需要兩臺機器,這裡選取3臺機器組成的伺服器叢集為例。在叢集初始化階段,當有一臺伺服器Server1啟動時,其單獨無法進行和完成Leader選舉,當第二臺伺服器Server2啟動時,此時兩臺機器可以相互通訊,每臺機器都試圖找到Leader,於是進入Leader選舉過程。選舉過程如下
(1) 每個Server發出一個投票。由於是初始情況,Server1和Server2都會將自己作為Leader伺服器來進行投票,每次投票會包含所推舉的伺服器的myid和ZXID,使用(myid, ZXID)來表示,此時Server1的投票為(1, 0),Server2的投票為(2, 0),然後各自將這個投票發給叢集中其他機器。
(2) 接受來自各個伺服器的投票。叢集的每個伺服器收到投票後,首先判斷該投票的有效性,如檢查是否是本輪投票、是否來自LOOKING狀態的伺服器。
(3) 處理投票。針對每一個投票,伺服器都需要將別人的投票和自己的投票進行PK,PK規則如下
· 優先檢查ZXID。ZXID比較大的伺服器優先作為Leader。
· 如果ZXID相同,那麼就比較myid。myid較大的伺服器作為Leader伺服器。
對於Server1而言,它的投票是(1, 0),接收Server2的投票為(2, 0),首先會比較兩者的ZXID,均為0,再比較myid,此時Server2的myid最大,於是更新自己的投票為(2, 0),然後重新投票,對於Server2而言,其無須更新自己的投票,只是再次向叢集中所有機器發出上一次投票資訊即可。
(4) 統計投票。每次投票後,伺服器都會統計投票資訊,判斷是否已經有過半機器接受到相同的投票資訊,對於Server1、Server2而言,都統計出叢集中已經有兩臺機器接受了(2, 0)的投票資訊,此時便認為已經選出了Leader。
(5) 改變伺服器狀態。一旦確定了Leader,每個伺服器就會更新自己的狀態,如果是Follower,那麼就變更為FOLLOWING,如果是Leader,就變更為LEADING
選舉流程簡述
目前有5臺伺服器,每臺伺服器均沒有資料,它們的編號分別是1,2,3,4,5,按編號依次啟動,它們的選擇舉過程如下:
- 伺服器1啟動,給自己投票,然後發投票資訊,由於其它機器還沒有啟動所以它收不到反饋資訊,伺服器1的狀態一直屬於Looking。
- 伺服器2啟動,給自己投票,同時與之前啟動的伺服器1交換結果,由於伺服器2的編號大所以伺服器2勝出,但此時投票數沒有大於半數,所以兩個伺服器的狀態依然是LOOKING。
- 伺服器3啟動,給自己投票,同時與之前啟動的伺服器1,2交換資訊,由於伺服器3的編號最大所以伺服器3勝出,此時投票數正好大於半數,所以伺服器3成為領導者,伺服器1,2成為小弟。
- 伺服器4啟動,給自己投票,同時與之前啟動的伺服器1,2,3交換資訊,儘管伺服器4的編號大,但之前伺服器3已經勝出,所以伺服器4只能成為小弟。
- 伺服器5啟動,後面的邏輯同伺服器4成為小弟。
2. 伺服器執行時期的Leader選舉
在Zookeeper執行期間,Leader與非Leader伺服器各司其職,即便當有非Leader伺服器當機或新加入,此時也不會影響Leader,但是一旦Leader伺服器掛了,那麼整個叢集將暫停對外服務,進入新一輪Leader選舉,其過程和啟動時期的Leader選舉過程基本一致。假設正在執行的有Server1、Server2、Server3三臺伺服器,當前Leader是Server2,若某一時刻Leader掛了,此時便開始Leader選舉。選舉過程如下
(1) 變更狀態。Leader掛後,餘下的非Observer伺服器都會講自己的伺服器狀態變更為LOOKING,然後開始進入Leader選舉過程。
(2) 每個Server會發出一個投票。在執行期間,每個伺服器上的ZXID可能不同,此時假定Server1的ZXID為123,Server3的ZXID為122;在第一輪投票中,Server1和Server3都會投自己,產生投票(1, 123),(3, 122),然後各自將投票傳送給叢集中所有機器。
(3) 接收來自各個伺服器的投票。與啟動時過程相同。
(4) 處理投票。與啟動時過程相同,此時,Server1將會成為Leader。
(5) 統計投票。與啟動時過程相同。
2.3 Leader選舉實現細節
1. 伺服器狀態
伺服器具有四種狀態,分別是LOOKING、FOLLOWING、LEADING、OBSERVING。
LOOKING:尋找Leader狀態。當伺服器處於該狀態時,它會認為當前叢集中沒有Leader,因此需要進入Leader選舉狀態。
FOLLOWING:跟隨者狀態。表明當前伺服器角色是Follower。
LEADING:領導者狀態。表明當前伺服器角色是Leader。
OBSERVING:觀察者狀態。表明當前伺服器角色是Observer。
2. 投票資料結構
每個投票中包含了兩個最基本的資訊,所推舉伺服器的SID和ZXID,投票(Vote)在Zookeeper中包含欄位如下
id:被推舉的Leader的SID。
zxid:被推舉的Leader事務ID。
electionEpoch:邏輯時鐘,用來判斷多個投票是否在同一輪選舉週期中,該值在服務端是一個自增序列,每次進入新一輪的投票後,都會對該值進行加1操作。
peerEpoch:被推舉的Leader的epoch。
state:當前伺服器的狀態。
(6) 改變伺服器的狀態。與啟動時過程相同。