Zookeeper之選舉源碼分析閱讀

Zookeeper 選舉相關源碼

準備:

生產者/消費者的多線程模型

責任鏈設計模式

zk 4.4.14 版本

一、選舉閱讀前瞭解

再分析源碼之前,先了解整個過程

leader 選舉存在與兩個階段中,

一個是服務器啓動時的leader 選舉。

另一個是運行過程中leader 節點宕機導致的leader選舉

1、選舉相關參數

a、服務器ID(myid)

集羣中每臺服務器都有獨一無二的編號,編號越大再選擇算法中的權重越大

b、zxid事務ID

值越大說明數據越新,再選舉算法中的權重也越大

c、邏輯始終(epoch-logicalclock)

或者叫投票的次數,同一輪投票過程中的邏輯始終值是相同的。每投完一次票這個數據就會增加,然後與其它服務器返回的投票信息中的數據相比,根據不同的值做出不同的判定。

d、選舉狀態
  • LOOKING,競選狀態
  • FOLLOWER ,隨從狀態,同步leader 狀態,參與投票
  • OBSERVING,觀察狀態,同步leader 狀態,不參與投票
  • LEADING,領導者狀態

二、選舉邏輯

1、服務啓動時的 leader 選舉

每個節點啓動的時候狀態都是LOOKKING,處於觀望狀態,接下來就開始進行選主流程

​ 若進行 Leader 選舉,則至少需要兩臺機器,這裏選取 3 臺機器組成的服務器集羣爲例。再集羣初始化階段,當有一臺服務器server1 啓動時,其單無法進行和完成選舉,當第二臺服務器 server2 啓動時,此時兩臺機器可以進行通信,每臺機器都試圖找到 Leader,於是進入 Leader 選舉過程。選舉過程如下:

(1)、每個 Server 發出一個投票。由於是初始情況,Server1 和 Server2 都會將自己作爲Leader 服務器來進行投票,每次投票會包含所推舉的服務器的 myid 和 ZXID、epoch,使用(myid、ZXID、epoch)來表示,此時 Server1 的投票爲(1,0),Server2 的投票爲(2,0),然後各自將這個投票發給集羣中其他機器。

(2)、接受來自各個服務器的投票。集羣的每個服務器收到投票後,首先判斷該投票的有效性,如檢查是否是本輪投票(epoch)、是否來自LOOKING 狀態的服務器。

(3)、處理投票。針對每一個投票,服務器都需要將別人的投票和自己的投票進行 PK,PK 規則如下

  • 優先epoch
  • 其次檢查ZXID。ZXID 比較大的服務器優先作爲Leader
  • 如果ZXID 相同,那麼就比較 myid。myid 較大的服務器作爲 Leader 服務器。
    • 所以對於Servier1 而言,它的投票是(1,0),接受Server2的投票爲(2,0),首先會比較兩者的ZXID,均爲0,再比較myid,此時Server2 的myid 最大,於是更新自己的投票爲(2,0),然後重新投票,對於Server2 而言,其無需更新自己的投票,只是再次向集羣中所有機器發出一次投票信息即可。

(4)、統計投票。每次投票 後,服務器都會統計投票信息,判斷是否已經有過半機器接受到相同的投票信息。對於Server1、Server2而言,都統計出集羣中已經有兩臺機器接受(2,0)的投票信息,此時便認爲已經選出了Leader。

(5)、改變服務器狀態。一旦確定了 Leader,每個服務器就會更新自己的狀態,如果是 Follower ,那麼就變更爲 FOLLOWER,如果是 Leader ,就變更爲Leader

2、運行過程中的選舉

​ 當集羣中的 Leader 服務器出現宏機或者不可用的情況時,那麼整個集羣將無法對外提供服務,而是進入新一輪的 Leader 選舉,服務器運行期間的 Leader 選舉和啓動期間的 Leader 選舉基本過程是一致的。

(1)、變更狀態。 Leader 掛了後,餘下的非 Observer 服務器都會將自己的服務器狀態更爲LOOKING,然後進入 Leader 選舉過程。

(2)、每個Server會發出一個投票。在運行期間,每個服務器上的ZXID 可能不同,此時假定 Server1的ZXID 爲123, Server3 的ZXID 爲 122; 在第一輪投票中,Server1 和 Server3 都會投自己,產生投票(1,123),(3,122),然後各自將投票發送給集羣中所有機器。接收來自各個服務器的投票。與啓動時過程相同。

(3)、處理投票。與啓動是過程相同,此時,Server1 將會成爲 Leader/

(4)、統計投票。與啓動時過程相同。

(5)、改變服務器的狀態**。與啓動時過程相同

三、選舉相關源碼

有興趣的朋友可以看看, 裏面基本就是把通訊邏輯弄好了就ok了,採用的是消費者/生產者模型

已翻譯了的Zookeeper源碼地址:https://gitee.com/kylin1991_admin/zookeeper/tree/branch-3.4.14/

相關流程圖:http://assets.processon.com/chart_image/5ea0c6cde0b34d05e1a5a16c.png

1、Leader選舉的源碼分析

QuorumPeerMainQuorumPeerFasstLeaderElectionMessengermian()方法rumFromConfig()QuorumPeer.start()進入線程的start()方法startLeaderElection()createElectionAlgorithm()構建選舉算法starter()構建Messenge()WorkerSender 線程WorkerReceiver線程QuorumPeerMainQuorumPeerFasstLeaderElectionMessenger選舉的源碼分析

2、zkServer 服務啓動邏輯

QuorumPeerMain QuorumPeerQuorumPeerMainmian()方法rumFromConfig()ServerCnxnFactory.createFactory()cnxnFactory.configure()quorumPeer.start()進入相關啓動start()cnxnFactory.start()QuorumPeerMain QuorumPeerQuorumPeerMain服務啓動邏輯

3、選舉流程分析

QuorumPeerFastLeaderElectionQuorumMajrun()方法FastLeaderElection.lookForLeader()進入選舉termPredicat()判斷是否結束是否可以選出LeadercontainsQuorum()選舉算法QuorumPeerFastLeaderElectionQuorumMaj選舉流程分析

4、投票的網絡通信流程

FastLeaderElectionQuorumCnxManagerQuorumCnxManlookForLeader()方sendqueue()調用toSend()toSend()startConnection()run()調用receiveConnection())handleConnection()FastLeaderElectionQuorumCnxManagerQuorumCnxMan投票的網絡通信流程

5、選舉完成之後的處理邏輯

沒說明說的,就是

FOLLOWER:makeFollower() 然後 followLeader()

LEADER:makerLeader 然後 lead()

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