zookeeper 半數選舉過程

前言

在講解流程之前,先說明一下選舉流程中涉及到的角色,以及涉及到的關鍵類和變量(源碼參考版本:3.4.9):

要半數以上的機器投票自己,自己才能是leader。若是4臺則必須 是3臺投自己。

怎麼算機器總數,是在配置文件中配置的節點數(即使其中某幾個沒有啓動)

角色:1.LOOKING:競選

           2.OBSERVING:觀察

           3.FOLLOWING:跟隨者

           4.LEADER:領導者

投票信息:

           1.logicalclock(electionEpoch):本地選舉週期,每次投票都會自增

           2.epoch(peerEpoch):選舉週期,每次選舉最終確定完leader結束選舉流程時會自增(真正zxid的前32位)

           3.zxid:數據事務ID,每次數據變動都會自增(真正zxid的後32位,zxid一共64位)

           4.sid:該投票信息所屬的serverId,即配置的myid文件中的值

           5.leader:提議的leader(被提議的server的serverId,即sid)

投票比較規則:

          1.logicalclock 大的勝出,否則進行步驟2

          2.zxid大的勝出,否則進行步驟3

          3.sid大的勝出
 

 

 

 

FastLeaderElection:選舉算法核心

  · 外部投票:特指其他服務器發來的投票。

  · 內部投票:服務器自身當前的投票。

  · 選舉輪次:Zookeeper服務器Leader選舉的輪次,即logicalclock。

  · PK:對內部投票和外部投票進行對比來確定是否需要變更內部投票。

  (1) 選票管理

  · sendqueue:選票發送隊列,用於保存待發送的選票。

  · recvqueue:選票接收隊列,用於保存接收到的外部投票。

  · WorkerReceiver:選票接收器。其會不斷地從QuorumCnxManager中獲取其他服務器發來的選舉消息,並將其轉換成一個選票,然後保存到recvqueue中,在選票接收過程中,如果發現該外部選票的選舉輪次小於當前服務器的,那麼忽略該外部投票,同時立即發送自己的內部投票。

  · WorkerSender:選票發送器,不斷地從sendqueue中獲取待發送的選票,並將其傳遞到底層QuorumCnxManager中。

  (2) 算法核心

  上圖展示了FastLeaderElection模塊是如何與底層網絡I/O進行交互的。Leader選舉的基本流程如下

  1. 自增選舉輪次。Zookeeper規定所有有效的投票都必須在同一輪次中,在開始新一輪投票時,會首先對logicalclock進行自增操作。

  2. 初始化選票。在開始進行新一輪投票之前,每個服務器都會初始化自身的選票,並且在初始化階段,每臺服務器都會將自己推舉爲Leader。

  3. 發送初始化選票。完成選票的初始化後,服務器就會發起第一次投票。Zookeeper會將剛剛初始化好的選票放入sendqueue中,由發送器WorkerSender負責發送出去。

  4. 接收外部投票。每臺服務器會不斷地從recvqueue隊列中獲取外部選票。如果服務器發現無法獲取到任何外部投票,那麼就會立即確認自己是否和集羣中其他服務器保持着有效的連接,如果沒有連接,則馬上建立連接,如果已經建立了連接,則再次發送自己當前的內部投票。

  5. 判斷選舉輪次。在發送完初始化選票之後,接着開始處理外部投票。在處理外部投票時,會根據選舉輪次來進行不同的處理。

    · 外部投票的選舉輪次大於內部投票。若服務器自身的選舉輪次落後於該外部投票對應服務器的選舉輪次,那麼就會立即更新自己的選舉輪次(logicalclock),並且清空所有已經收到的投票箱,然後使用初始化的投票來進行PK以確定是否變更內部投票。最終再將內部投票發送出去。

    · 外部投票的選舉輪次小於內部投。若服務器接收的外選票的選舉輪次落後於自身的選舉輪次,那麼Zookeeper就會直接忽略該外部投票,不做任何處理,並返回步驟4。

    · 外部投票的選舉輪次等於內部投票。此時可以開始進行選票PK。

  6. 選票PK。在進行選票PK時,符合任意一個條件就需要變更投票。

    · 若外部投票中推舉的Leader服務器的選舉輪次大於內部投票,那麼需要變更投票。

    · 若選舉輪次一致,那麼就對比兩者的ZXID,若外部投票的ZXID大,那麼需要變更投票。

    · 若兩者的ZXID一致,那麼就對比兩者的SID,若外部投票的SID大,那麼就需要變更投票。

  7. 變更投票。經過PK後,若確定了外部投票優於內部投票,那麼就變更投票,即使用外部投票的選票信息來覆蓋內部投票,變更完成後,再次將這個變更後的內部投票發送出去。

  8. 選票歸檔。無論是否變更了投票,都會將剛剛收到的那份外部投票放入選票集合recvset中進行歸檔。recvset用於記錄當前服務器在本輪次的Leader選舉中收到的所有外部投票(按照服務隊的SID區別,如{(1, vote1), (2, vote2)...})。

  9. 統計投票。完成選票歸檔後,就可以開始統計投票,統計投票是爲了統計集羣中是否已經有過半的服務器認可了當前的內部投票,如果確定已經有過半服務器認可了該投票,則終止投票。否則返回步驟4。

  10. 更新服務器狀態。若已經確定可以終止投票,那麼就開始更新服務器狀態,服務器首選判斷當前被過半服務器認可的投票所對應的Leader服務器是否是自己,若是自己,則將自己的服務器狀態更新爲LEADING,然後廣播出去,若不是,則根據具體情況來確定自己是FOLLOWING或是OBSERVING。

  以上10個步驟就是FastLeaderElection的核心,其中步驟4-9會經過幾輪循環,直到有Leader選舉產生。

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章