一個 Raft 集羣包含若干個服務器節點;一般是 5 個,這容許整個系統容忍 2 個節點的失效,每一個節點處於如下三種狀態之一:算法
follower(跟隨者)
:全部結點都以 follower
的狀態開始。若是沒收到 leader
消息則會變成 candidate
狀態。candidate(候選人)
:會向其餘結點「拉選票」,若是獲得大部分的票則成爲leader
。這個過程就叫作Leader選舉(Leader Election)。leader(領導者)
:全部對系統的修改都會先通過leader
。Raft經過選出一個leader來簡化日誌副本的管理,例如,日誌項(log entry)只容許從leader流向follower。安全
基於leader的方法,Raft算法能夠分解成三個子問題:服務器
Leader election
(領導選舉):原來的leader掛掉後,必須選出一個新的leader動畫
Log replication
(日誌複製):leader從客戶端接收日誌,並複製到整個集羣中spa
Safety
(安全性):若是有任意的server將日誌項回放到狀態機中了,那麼其餘的server只會回放相同的日誌項日誌
Raft 使用一種心跳機制來觸發領導人選舉。當服務器程序啓動時,他們都是 follower
(跟隨者) 身份。若是一個跟隨者在一段時間裏沒有接收到任何消息,也就是選舉超時,而後他就會認爲系統中沒有可用的領導者而後開始進行選舉以選出新的領導者。要開始一次選舉過程,follower
會給當前term加1而且轉換成candidate
狀態。code
而後他會並行的向集羣中的其餘服務器節點發送請求投票的 RPCs 來給本身投票。候選人的狀態維持直到發生如下任何一個條件發生的時候,server
他本身贏得了此次的選舉rem
其餘的服務器成爲領導者get
若是在等待選舉期間,candidate接收到其餘server要成爲leader的RPC,分兩種狀況處理:
candidate
會轉成follower
狀態leader
,並繼續保持candidate
狀態一段時間以後沒有任何一個獲勝的人
當選出 leader
後,它會開始接受客戶端請求,每一個請求會帶有一個指令,能夠被回放到狀態機中。leader
把指令追加成一個log entry
,而後經過AppendEntries RPC並行的發送給其餘的server,當改entry被多數派server複製後,leader
會把該entry回放到狀態機中,而後把結果返回給客戶端。
當 follower
宕機或者運行較慢時,leader
會無限地重發AppendEntries給這些follower,直到全部的follower都複製了該log entry。
raft的log replication保證如下性質(Log Matching Property):
其中特性一經過如下保證:
特性二經過如下保證:
若是follower沒有發現與它同樣的log entry,那麼它會拒絕接受新的log entry 這樣就能保證特性二得以知足。
在一些一致性算法中,即便一臺server沒有包含全部以前已提交的log entry,也能被選爲主,這些算法須要把leader上缺失的日誌從其餘的server拷貝到leader上,這種方法會致使額外的複雜度。相對而言,raft使用一種更簡單的方法,即它保證全部已提交的log entry都會在當前選舉的leader上,所以,在raft算法中,日誌只會從leader流向follower。
爲了實現上述目標,raft在選舉中會保證,一個candidate只有獲得大多數的server的選票以後,才能被選爲主。獲得大多數的選票代表,選舉它的server中至少有一個server是擁有全部已經提交的log entry的,而leader的日誌至少和follower的同樣新,這樣就保證了leader確定有全部已提交的log entry。
領導人知道一條當前任期內的日誌記錄是能夠被提交的,只要它被存儲到了大多數的服務器上。若是一個領導人在提交日誌條目以前崩潰了,將來後續的領導人會繼續嘗試複製這條日誌記錄。然而,一個領導人不能判定一個以前任期裏的日誌條目被保存到大多數服務器上的時候就必定已經提交了。下圖展現了一種狀況,一條已經被存儲到大多數節點上的老日誌條目,也依然有可能會被將來的領導人覆蓋掉。
如上圖的例子,圖(c)就發生了一個log entry雖然已經複製到大多數的服務器,可是仍然有可能被覆蓋掉的可能,如圖(d),整個發生的時序以下:
爲了上圖描述的狀況,Raft 永遠不會經過計算副本數目的方式去提交一個以前任期內的日誌條目。只有領導人當前任期裏的日誌條目經過計算副本數目能夠被提交;一旦當前任期的日誌條目以這種方式被提交,那麼因爲日誌匹配特性,以前的日誌條目也都會被間接的提交。例如,圖e中,若是S1在掛掉前把log entry(4)複製到了大多數的server後,就能保證以前的log entry(2)被提交了,以後S5也就不可能被選爲領導者了。
以反證法來證實,假設任期 T 的領導人(領導人 T)在任期內提交了一條日誌條目,可是這條日誌條目沒有被存儲到將來某個任期的領導人的日誌中。設大於 T 的最小任期 U 的領導人 U 沒有這條日誌條目。
若是 S1 (任期 T 的領導者)提交了一條新的日誌在它的任期裏,而後 S5 在以後的任期 U 裏被選舉爲領導人,而後至少會有一個機器,如 S3,既擁有來自 S1 的日誌,也給 S5 投票了。
投票者把本身選票投給領導人 U 時,領導人 U 的日誌必須和投票者本身同樣新。這就致使了二者矛盾之一。
跟隨者或者候選人崩潰,會按以下處理:
領導人選舉是 Raft 中對時間要求最爲關鍵的方面。Raft 能夠選舉並維持一個穩定的領導人,只要系統知足下面的時間要求:
廣播時間(broadcastTime) << 選舉超時時間(electionTimeout) << 平均故障間隔時間(MTBF)
選舉超時時間要大於廣播時間的緣由是,防止跟隨者由於還沒收到領導者的心跳,而從新選主。
選舉超時時間要小於MTBF的緣由是,防止選舉時,能正常工做的server沒有達到大多數。
對於廣播時間,通常在[0.5ms,20ms]之間,而平均故障間隔時間通常很是大,至少是按照月爲單位。所以,通常選舉超時時間通常選擇範圍爲[10ms,500ms]。所以,當領導者掛掉後,能在較短期內從新選主。