記錄一下對Raft算法的理解,算法的內容比較多,所以准備將算法的全部過程分成四個部分來寫。分別是
該文章為第一部分。
Raft算法之Leader選舉
簡單介紹
首先需要了解Raft中的一個關鍵詞:Term
,本文中以下部分簡單稱為任期。任期通過連續的整數編號表示並且是單調遞增的,代表任意長度的一段時間。在網絡中所有服務器都有自己的任期編號,在網絡中大部分正常運行階段,所有服務器的任期號都是相同的。
Raft算法中服務器主要分為三種角色:Leader
,Follower
,Candidate
,並且三種角色相互獨立,也就是服務器在同一時間內只可能扮演其中一種角色。
Leader
:用於對所有用戶的請求進行處理。以及之后要說明的日志的復制等等。Follower
:不會主動發送消息,只響應來自Leader
與Candidate
的請求。Candidate
:用於選舉新的Leader
。
在本文介紹的范圍內,網絡狀態分為兩種情況:選舉階段,正常運行階段。(網絡狀態還可能會有成員變化階段,但不在本文范圍內,所以暫時先不考慮).
並且每一個任期都是以選舉階段開始。但不一定以正常運行階段結束。在某些情況下一個完整的任期可能全部為選舉階段。如下圖:
選舉階段->正常運行階段
在網絡初始化時,網絡中所有的服務器都以Follower
的角色啟動。由於Follower
只被動接收消息。所以全網中所有服務器都處於等待狀態。同時每一個服務器都在本地維護一個計時器。
- 計時器的作用很簡單,就是判斷當前階段(選舉階段或正常運行階段)是否超時。而當計時器超時后,任期將會
所以在網絡啟動后所有服務器等待指定長度的一段時間過去以后。計時器將會超時。這時候計時器超時的服務器將轉換自己的角色為Candidate
。進入選舉階段。而進入選舉階段的Candidate
將會做以下幾件事:
- 將自己的任期號加1.
- 為自己投一票用以選舉出新的
Leader
。 - 將本地的計時器重置
- 發送投票請求到網絡中的其他所有的服務器。
- 等待下一次的計時器超時
同時選舉Leader
具有以下幾點要求:
- 每個服務器在一個任期內只能投一票,並且使先到者先得(即投票給自己收到的第一個請求投票的,滿足要求的服務器的請求)
- 請求投票的消息中需要帶有請求者所處的當前任期號。
- 投票者只會投票給任期號大於等於自己當前任期號的服務器。
- 關於日志的要求(下一篇文章再介紹)
在選舉狀態會出現三種結果:
- 自己成功當選
Leader
- 網絡中其他服務器當選
Leader
- 網絡中沒有服務器當選
Leader
當網絡中某一個Candidate
接收到網絡中大多數成員的投票后,即可將自己的身份轉換為Leader
。在當選Leader
后,該服務器將周期性地發送心跳信息(心跳信息包含成功當選Leader
的服務器的當前任期號)到網絡中其他服務器。在網絡中其他的服務器收到心跳信息后檢查心跳消息中的任期號是否大於等於自己的任期號。如果滿足該條件的話Candidate
將會轉換為Follower
狀態,並重置計時器。而如果任期號小於自己的任期號,服務器將拒絕該心跳消息並繼續處於Candidate
狀態。
第三種情況為網絡中沒有服務器成功當選Leader
。這種情況在當很多Follower
同時成為Candidate
時會發生。因為當角色轉換為Candidate
后將會將選票投給自己。從而導致選票被分散開來,沒有Candidate
可以得到網絡中大部分節點的選票。從而沒有節點可以成為Leader
.這種情況下計時器將再次超時,網絡狀態將從選舉階段進入下一個選舉階段。同時Candidate
將會再次執行上面說明的幾件事。
Raft算法采用了隨機選舉超時機制來避免出現這種情況。即當計時器超時后,服務器將隨機延遲指定的時間后才進入選舉階段。
由於隨機延遲的原因,將降低服務器在同一時間選舉超時的情況,可以有效避免選票分散的情況。
正常運行階段->選舉階段
當Leader
成功選舉之后,將周期性發送心跳消息到網絡中其他服務器。同時其他服務器將轉換自己的角色為Follower
。並且每次收到心跳消息后都會重置自己的計時器,防止超時再次進入選舉階段。
而如果Leader
因為特殊情況崩潰時,網絡中的其他服務器將不再接收到心跳消息,在等待指定時間后計時器將會超時,從而再次進入選舉階段。
- 而如果
Leader
崩潰時間較短,可以在其他服務器計時器超時之間恢復,並發送心跳消息,網絡仍然可以恢復為Leader
崩潰之前的狀態。 - 如果
Leader
崩潰時間較長,在網絡中已有新的Leader
選舉產生后恢復,由於舊的Leader
任期號將小於新的Leader
,在舊的Leader
接收到新的Leader
發送的心跳消息后則會變為Follower
狀態。
總結
三種角色的轉換情況:

Candidate
服務器角色變為Candidate
后:
- 將自己的任期號加1.
- 為自己投一票用以選舉出新的
Leader
。 - 將本地的計時器重置
- 發送投票請求到網絡中的其他所有的服務器。
- 等待下一次的計時器超時
- 當接收到心跳消息(心跳消息中的任期號大於等於自己的任期號)后,變為
Follower
狀態。 - 計時器超時,再次執行上面的5件事。
- 當自己接收到大多數選票后,變為
Leader
狀態。
Follower
服務器角色變為Follower
后:
- 等待
Leader
或者Candidate
發送消息給自己。- 如果是心跳消息(心跳消息中的任期號大於等於自己的任期號),則重置計時器。
- 如果是選舉消息(選舉消息中的任期號大於自己的任期號),則將自己變為
Candidate
,任期號更新為選舉消息中的較大的任期號。重置計時器並返回投票響應信息。
- 或者網絡處於正常運行狀態時,如果收到客戶端請求,將會將該請求重定向到
Leader
。 - 如果在指定時間間隔內沒有收到心跳消息或者是選舉消息,則角色變為
Candidate
。
Leader
服務器角色變為Leader
后:
- 重置計時器,並周期性發送心跳消息(帶有自己的任期號)到網絡中其他服務器。
- 等待客戶端請求消息。
下一篇文章:Raft算法之日志復制