Raft系列文章之二:Leader選舉

上一篇文章我們介紹了多副本狀態機,Raft就是一個維護着多副本日誌的多副本狀態機。

Raft首先會選舉出一個唯一的Leader, Leader負責管理日誌,所用對日誌的添加和狀態變化操作都通過Leader完成。Leader接受用戶的日誌請求並將日誌分發給系統中其他節點。並告知其他節點何時可以安全地將日誌應用到狀態機上。這種方式簡化了多副本日誌的管理,日誌的數據流向是從Leader到其他節點,而其他節點不會發送日誌給Leader,非常簡單。Leader當掉時,Raft會選出一個新的Leader。

通過採用Leader, Raft把一致性問題分解爲相互獨立的3個子問題:

Leader選舉:系統初始化時需要選出Leader, Leader當掉時選出新的Leader。

日誌分發:Leader接受日誌請求並分發給其他節點。

確保正確性:確保所有日誌副本是一致的。

本文只介紹Leader選舉過程,其他兩個子問題我會在後面的文章中介紹。

節點的狀態與日誌

在Raft集羣中,任何一個節點在任何一個時刻都處於三種狀態之一:Leader, Follower, Candidate。在系統正常運行的絕大部分時間,系統中會有一個Leader, 其他都是Follower。由Leader接受用戶的請求,每個用戶請求視爲一項日誌。在Raft語境下,我們所說的日誌並不是系統運行的錯誤,警告,Debug信息等,而是指操作記錄。例如提供鍵值對存儲的Raft集羣,日誌是指 "設置A=100",  "設置B=3", "刪除C"這種引起狀態變化的鍵值對的操作, 而查看A的值並不是日誌,因爲它不會引起系統狀態的變化。Follower是被動的,只接受來自Leader和Candidate的請求,自己不會發出任何請求。Candidate狀態是在Leader選舉過程中的臨時狀態。下圖描述了3中狀態之間的轉換關係:


任期

Raft把時間分爲連續的任期(term),每個任期可以是任意時長,任期用連續的整數進行標號。每個任期首先進行Leader選舉,選舉時,多個Candidate競爭成爲Leader,一旦某個節點成爲Leader,其他節點則變回Follower,成爲Leader的節點將在該任期內一致擔任Leader,如果該Leader節點發生故障,其他節點會在新的任期內進行選舉。任何一個任期內都不會有多個Leader。Raft系統中,任期是一個及其重要的概念,每個節點都維護着當前任期的值,每次節點間的通信都包含任期信息,每個節點在檢測到自己的任期值低於其他節點,都會更新自己的任期值,設置爲檢測到的較高的值。當Leader和Candidate發現自己的任期低於別的節點,則立即把自己轉換爲Follower。

RPC

Raft節點間的通信採用RPC調用, Raft算法核心部分只需要用到兩個RPC: RequestVote和AppendEntries。RequestVote RPC由Candidate發起用於Leader選舉。AppendEntries RPC由Leader發起,用於心跳和日誌複製。而Follower不會發起任何RPC。

Leader選舉過程

Raft採用心跳機制觸發Leader選舉。當系統啓動時,所有節點初始化爲Follower狀態,設置任期爲0,並啓動計時器,計時器超時後,Follower節點轉化爲Candidate節點,一旦轉化爲Candidate節點,立即開始一下幾件事情:

1.增加自己的任期數

2. 啓動一個新的計時器

3. 給自己投一票

4.向所有其他節點發送RequestVote RPC請求,並等待其他節點回復。

如果在計時器超時前接收到多數節點的同意投票,則轉換爲Leader。如果接受到其他節點的AppendEntries心跳RPC,說明其他節點已經被選爲Leader, 則轉換爲Follower。如果計時器超時時還沒有接受到以上兩種信息中的任何一種,則重複步驟1-4,進行新的選舉。

節點在接受到多數節點的投票成爲Leader後,會立即向所有節點發送AppendEntries 心跳RPC。所有Candidate收到心跳RPC後,轉換爲Follower,選舉結束。

每個Follower在一個任期內只能投一票,採取先到先得的策略。每個Follower有一個計時器,在計時器超時時仍然沒有接受到來自Leader的心跳RPC, 則轉換爲Candidate, 開始請求投票。也就是在當期Leader當掉後,就會有Follower開始轉換爲Candidate開始投票。

如果多個節點同時發起投票,每個節點都沒有拿到多數票(這種情況成爲Split Vote),則增加任期數,在新的任期內重新進行投票。有沒有可能Split Vote反覆發生,永遠都選不出Leader呢?

Raft採取隨機超時時間,Raft系統有一個選舉超時配置項,Follower和Candidate的計時器超時時間每次重新計算,隨機選取配置時間的1倍到2倍之間。即使所有節點同時啓動,由於隨機超時時間的設置,各個節點一般不會同時轉爲Candidate,先轉爲Candidate的節點會先發起投票,從而獲得多數票。因而在每個任期內,多個節點同時請求投票並且都只獲得少數票的機率很小,連續多次發生這種情況機率更小,理論上機率很小,實際上可以認爲完全不可能發生。在我的Raft實現中,基本上都在1-2個任期內選出Leader。

下一篇文章我將詳細介紹Raft RPC RequestVote 和AppendEntries。

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