一致性演算法 - Raft
Raft 狀態
一個 Raft 叢集包含若干個伺服器節點;通常是 5 個,這允許整個系統容忍 2 個節點的失效,每個節點處於以下三種狀態之一:
follower(跟隨者)
:所有結點都以 follower
的狀態開始。如果沒收到 leader
訊息則會變成 candidate
狀態。
candidate(候選人)
:會向其他結點“拉選票”,如果得到大部分的票則成為leader
。這個過程就叫做Leader選舉(Leader Election)。
leader(領導者)
:所有對系統的修改都會先經過leader
。
Raft 一致性演算法
Raft通過選出一個leader來簡化日誌副本的管理,例如,日誌項(log entry)只允許從leader流向follower。
基於leader的方法,Raft演算法可以分解成三個子問題:
Leader election
(領導選舉):原來的leader掛掉後,必須選出一個新的leader
Log replication
(日誌複製):leader從用戶端接收日誌,並複製到整個叢集中
Safety
(安全性):如果有任意的server將日誌項回放到狀態機器中了,那麼其他的server只會回放相同的日誌項
Leader election (領導選舉)
Raft 使用一種心跳機制來觸發領導人選舉。當伺服器程式啟動時,他們都是 follower
(跟隨者) 身份。如果一個跟隨者在一段時間裡沒有接收到任何訊息,也就是選舉逾時,然後他就會認為系統中沒有可用的領導者然後開始進行選舉以選出新的領導者。要開始一次選舉過程,follower
會給當前term加1並且轉換成candidate
狀態。
然後他會並行的向叢集中的其他伺服器節點發送請求投票的 RPCs 來給自己投票。候選人的狀態維持直到發生以下任何一個條件發生的時候,
Log replication (日誌複製)
當選出 leader
後,它會開始接受用戶端請求,每個請求會帶有一個指令,可以被回放到狀態機器中。leader
把指令追加成一個log entry
,然後通過AppendEntries RPC並行的發送給其他的server,當改entry被多數派server複製後,leader
會把該entry回放到狀態機器中,然後把結果返回給用戶端。
當 follower
宕機或者運行較慢時,leader
會無限地重發AppendEntries給這些follower,直到所有的follower都複製了該log entry。
raft的log replication保證以下性質(Log Matching Property):
- 如果兩個log entry有相同的index和term,那麼它們儲存相同的指令
- 如果兩個log entry在兩份不同的日誌中,並且有相同的index和term,那麼它們之前的log entry是完全相同的
其中特性一通過以下保證:
- leader在一個特定的term和index下,只會建立一個log entry
- log entry不會改變它們在日誌中的位置
特性二通過以下保證:
- AppendEntries會做log entry的一致性檢查,當發送一個AppendEntriesRPC時,leader會帶上需要複製的log entry前一個log entry的(index, iterm)
如果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),整個發生的時序如下:
- 圖a中,S1被選為主,然後複製到log index為2的log entry到S2上
- 圖b中,S1掛掉,然後S5獲得了S3,S4和自身的選舉,成為leader,然後,其從用戶端收到了一個新的log entry(3)
- 圖c中,S5掛掉,S1重新正常工作,又被選為主,繼續複製log entry(2),在log entry(2)被提交前,S1又掛掉
- 圖d中,S5又重新被選為領導者,然後,會把term 3的log entry覆蓋到其他log index為2的log entry
為了描述的情況,Raft 永遠不會通過計算副本數目的方式去提交一個之前任期內的日誌條目。只有領導人當前任期裡的日誌條目通過計算副本數目可以被提交;一旦當前任期的日誌條目以這種方式被提交,那麼由於日誌匹配特性,之前的日誌條目也都會被間接的提交。例如,圖e中,如果S1在掛掉前把log entry(4)複製到了大多數的server後,就能保證之前的log entry(2)被提交了,之後S5也就不可能被選為領導者了。
安全性論證
以反證法來證明,假設任期 T 的領導人(領導人 T)在任期內提交了一條日誌條目,但是這條日誌條目沒有被儲存到未來某個任期的領導人的日誌中。設大於 T 的最小任期 U 的領導人 U 沒有這條日誌條目。
如果 S1 (任期 T 的領導者)提交了一條新的日誌在它的任期裡,然後 S5 在之後的任期 U 裡被選舉為領導人,然後至少會有一個機器,如 S3,既擁有來自 S1 的日誌,也給 S5 投票了。
- 在領導人 U 選舉的時候一定沒有那條被提交的日誌條目(領導人從不會刪除或者覆蓋任何條目)。
- 領導人 T 複製這條日誌條目給叢集中的大多數節點,同時,領導人U 從叢集中的大多數節點贏得了選票。因此,至少有一個節點(投票者、選民)同時接受了來自領導人T 的日誌條目,並且給領導人U 投票了,這個投票者是產生這個矛盾的關鍵。
- 這個投票者必須在給領導人 U 投票之前先接受了從領導人 T 發來的已經被提交的日誌條目;否則他就會拒絕來自領導人 T 的附加日誌請求(因為此時他的任期號會比 T 大)。
- 投票者在給領導人 U 投票時依然保有這條日誌條目,因為任何中間的領導人都包含該日誌條目(根據上述的假設),領導人從不會刪除條目,並且跟隨者只有和領導人衝突的時候才會刪除條目。
投票者把自己選票投給領導人 U 時,領導人 U 的日誌必須和投票者自己一樣新。這就導致了兩者矛盾之一。
- 首先,如果投票者和領導人 U 的最後一條日誌的任期號相同,那麼領導人 U 的日誌至少和投票者一樣長,所以領導人 U 的日誌一定包含所有投票者的日誌。這是另一處矛盾,因為投票者包含了那條已經被提交的日誌條目,但是在上述的假設裡,領導人 U 是不包含的。
- 除此之外,領導人 U 的最後一條日誌的任期號就必須比投票人大了。此外,他也比 T 大,因為投票人的最後一條日誌的任期號至少和 T 一樣大(他包含了來自任期 T 的已提交的日誌)。建立了領導人 U 最後一條日誌的之前領導人一定已經包含了那條被提交的日誌(根據上述假設,領導人 U 是第一個不包含該日誌條目的領導人)。所以,根據日誌匹配特性,領導人 U 一定也包含那條被提交當然日誌,這裡產生矛盾。
- 因此,假設不成立,所有比 T 大的領導人一定包含了所有來自 T 的已經被提交的日誌。日誌匹配原則保證了未來的領導人也同時會包含被間接提交的條目
跟隨者和候選人崩潰
跟隨者或者候選人崩潰,會按如下處理:
- 領導者會不斷給它發送選舉和追加日誌的RPC,直到成功
- 跟隨者會忽略它已經處理過的追加日誌的RPC
時間和可用性
領導人選舉是 Raft 中對時間要求最為關鍵的方面。Raft 可以選舉並維持一個穩定的領導人,只要系統滿足下面的時間要求:
廣播時間(broadcastTime) << 選舉逾時時間(electionTimeout) << 平均故障間隔時間(MTBF)
- 廣播時間指的是從一個伺服器並行的發送 RPCs 給叢集中的其他伺服器並接收響應的平均時間;
- 選舉逾時時間就是選舉的逾時時間限制
- 平均故障間隔時間就是對於一台伺服器而言,兩次故障之間的平均時間。
選舉逾時時間要大於廣播時間的原因是,防止跟隨者因為還沒收到領導者的心跳,而重新選主。
選舉逾時時間要小於MTBF的原因是,防止選舉時,能正常工作的server沒有達到大多數。
對於廣播時間,一般在[0.5ms,20ms]之間,而平均故障間隔時間一般非常大,至少是按照月為單位。因此,一般選舉逾時時間一般選擇範圍為[10ms,500ms]。因此,當領導者掛掉後,能在較短時間內重新選主。
動畫示範 Raft
http://thesecretlivesofdata.c...