分佈式選舉-Raft算法-1 Leader選舉 原理

Raft理論是分佈式數據一致性算法,爲了便於理解Raft算法分成了4個部分:

  • Leader選舉

  • 日誌複製

  • 成員變更

  • 日誌壓縮

此係列文章先來分析Raft Leader選舉的原理及實現,在後續《分佈式數據複製》的系列文章中,我們再回過頭來實現Raft算法的其他功能。

 

Leader選舉:

選舉原則:典型的投票選舉算法(少數服從多數),也就是說,在一定週期內獲得投票最多的節點成爲主節點。

節點角色:

  • Leader,主節點,一個任值週期內只有一個主節點。

  • Candidate,候選節點,集羣中沒有Leader時發起投票,進行選舉。

  • Follower,跟隨節點,即主節點的從節點。

消息類型:

  • Vote,投票消息

  • Heartbeat,心跳消息,Follower接收Leader的心跳消息,重置選舉計時器。

選舉過程:

  1. 節點剛啓動時,默認是Follower狀態。

  2. 啓動之後,開啓選舉超時定時器,節點切換到Candidate狀態,發起選舉請求。

  3. 當Candidate狀態的節點,接收到超過半數的投票,則成爲主節點,切換到Leader狀態。每一輪選舉,每個節點只能投一次票。

  4. Leader狀態的節點向其他節點發送心跳消息,其他Candidate狀態的節點切換回Follower狀態,並重置選舉超時定時器。

  5. Leader節點收到更高任期號的消息,切換到Follower狀態。這種情況主要發生在有網絡分區時。

     假設有5個節點,選舉過程如下圖:

  1. 初始5個節點爲Follower狀態,任職週期爲1(Term=1)。

  2. 節點切換爲Candidate狀態,開啓選舉定時器,任值週期加1(Term=2)。先爲自己投票,然後向其他節點請求投票。

  3. 得票數超過節點半數的節點,切換爲Leader狀態,並向其他4個節點發送心跳消息。其他4個節點切換爲Follower狀態。

 

網絡分區:

下面看看,當發生網絡分區時,節點狀態如何切換。如下圖:

網絡發生A、B兩個分區,A分區的3個節點繼續提供服務。B分區的2個節點由於沒有收到Leader節點的心跳消息,在選舉定時器超時後,切換到Candidate狀態,開始進行投票選舉,任職週期加1(Term=3)。

當網絡恢復後,A分區節點的任值週期(Term=2)比B分區節點的任值週期(Term=3)小,因此A分區的節點切換成Follower狀態,5個節點開始進行投票選舉,最終選舉出Leader節點。

問題:如何避免網絡恢復後,不發生切主?

如上圖,B分區的2個節點由於永遠得不到超過半數的投票,所以任職週期不斷累加。當網絡恢復後,原來的Leader由於任職週期小,切換爲Follower狀態,集羣重新選主。

 

如何避免重新選主,將投票階段分拆成兩階段,即預投票階段和投票階段。

預投票階段:任職週期不累加,選出得票數過半的節點。

投票階段:由在預投票階段選出的節點發起投票請求,任職週期累加,最終選出主節點。

這樣,B分區2個節點的任值週期就會小於等於原Leader的任值週期,當網絡恢復後就不會重新選主。

 

開源軟件應用:Go語言編寫的etcd組件,是一個高可用,強一致的數據存儲倉庫,就是實現了Raft算法的選主和數據一致性,Kubernetes的選主就是使用的etcd組件。

 

總結:

Raft的選舉算法,節點有三個角色:Leader、Candidate、Follower。有兩種通信消息:投票消息,心跳消息。由選舉定時器開啓任值週期,在任值週期內得票過半的節點成爲主節點。

優點是算法複雜度低,易於實現,主節點穩定,不會輕易發生切主。缺點是集羣內節點需要全通信,通信量比較大。

 

Raft算法的Leader選舉原理講解完了,下一篇文章《分佈式選舉-Raft算法-2 Leader選舉 代碼實現》我們來具體看看如何用代碼實現分佈式環境下的Raft Leader選舉。


獲取Raft算法的實現代碼,請關注公衆號,後臺回覆“ Raft ”獲取源碼。

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