raft簡單介紹

一致性算法 - 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從客戶端接收日誌,並複製到整個集羣中spa

Safety (安全性):若是有任意的server將日誌項回放到狀態機中了,那麼其餘的server只會回放相同的日誌項日誌

Leader election (領導選舉)

Raft 使用一種心跳機制來觸發領導人選舉。當服務器程序啓動時,他們都是 follower(跟隨者) 身份。若是一個跟隨者在一段時間裏沒有接收到任何消息,也就是選舉超時,而後他就會認爲系統中沒有可用的領導者而後開始進行選舉以選出新的領導者。要開始一次選舉過程,follower 會給當前term加1而且轉換成candidate狀態。code

而後他會並行的向集羣中的其餘服務器節點發送請求投票的 RPCs 來給本身投票。候選人的狀態維持直到發生如下任何一個條件發生的時候,server

  • 他本身贏得了此次的選舉rem

    • 若是這個節點贏得了半數以上的vote就會成爲leader,每一個節點會按照first-come-first-served的原則進行投票,而且一個term中只能投給一個節點, 這樣就保證了一個term最多有一個節點贏得半數以上的vote。
    • 當一個節點贏得選舉, 他會成爲leader, 而且給全部節點發送這個信息, 這樣全部節點都會回退成follower。
  • 其餘的服務器成爲領導者get

    若是在等待選舉期間,candidate接收到其餘server要成爲leader的RPC,分兩種狀況處理:

    • 若是leader的term大於或等於自身的term,那麼改candidate 會轉成follower 狀態
    • 若是leader的term小於自身的term,那麼會拒絕該 leader,並繼續保持candidate 狀態
  • 一段時間以後沒有任何一個獲勝的人

    • 有可能,不少follower同時變成candidate,致使沒有candidate能得到大多數的選舉,從而致使沒法選出主。當這個狀況發生時,每一個candidate會超時,而後從新發增長term,發起新一輪選舉RPC。須要注意的是,若是沒有特別處理,可能出致使無限地重複選主的狀況。
    • Raft採用隨機定時器的方法來避免上述狀況,每一個candidate選擇一個時間間隔內的隨機值,例如150-300ms,採用這種機制,通常只有一個server會進入candidate狀態,而後得到大多數server的選舉,最後成爲主。每一個candidate在收到leader的心跳信息後會重啓定時器,從而避免在leader正常工做時,會發生選舉的狀況。

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 投票了。
  1. 在領導人 U 選舉的時候必定沒有那條被提交的日誌條目(領導人從不會刪除或者覆蓋任何條目)。
  2. 領導人 T 複製這條日誌條目給集羣中的大多數節點,同時,領導人U 從集羣中的大多數節點贏得了選票。所以,至少有一個節點(投票者、選民)同時接受了來自領導人T 的日誌條目,而且給領導人U 投票了,這個投票者是產生這個矛盾的關鍵。
  3. 這個投票者必須在給領導人 U 投票以前先接受了從領導人 T 發來的已經被提交的日誌條目;不然他就會拒絕來自領導人 T 的附加日誌請求(由於此時他的任期號會比 T 大)。
  4. 投票者在給領導人 U 投票時依然保有這條日誌條目,由於任何中間的領導人都包含該日誌條目(根據上述的假設),領導人從不會刪除條目,而且跟隨者只有和領導人衝突的時候纔會刪除條目。
  5. 投票者把本身選票投給領導人 U 時,領導人 U 的日誌必須和投票者本身同樣新。這就致使了二者矛盾之一。

    • 首先,若是投票者和領導人 U 的最後一條日誌的任期號相同,那麼領導人 U 的日誌至少和投票者同樣長,因此領導人 U 的日誌必定包含全部投票者的日誌。這是另外一處矛盾,由於投票者包含了那條已經被提交的日誌條目,可是在上述的假設裏,領導人 U 是不包含的。
    • 除此以外,領導人 U 的最後一條日誌的任期號就必須比投票人大了。此外,他也比 T 大,由於投票人的最後一條日誌的任期號至少和 T 同樣大(他包含了來自任期 T 的已提交的日誌)。建立了領導人 U 最後一條日誌的以前領導人必定已經包含了那條被提交的日誌(根據上述假設,領導人 U 是第一個不包含該日誌條目的領導人)。因此,根據日誌匹配特性,領導人 U 必定也包含那條被提交固然日誌,這裏產生矛盾。
  6. 所以,假設不成立,全部比 T 大的領導人必定包含了全部來自 T 的已經被提交的日誌。日誌匹配原則保證了將來的領導人也同時會包含被間接提交的條目

跟隨者和候選人崩潰

跟隨者或者候選人崩潰,會按以下處理:

  • 領導者會不斷給它發送選舉和追加日誌的RPC,直到成功
  • 跟隨者會忽略它已經處理過的追加日誌的RPC

時間和可用性

領導人選舉是 Raft 中對時間要求最爲關鍵的方面。Raft 能夠選舉並維持一個穩定的領導人,只要系統知足下面的時間要求:

廣播時間(broadcastTime) << 選舉超時時間(electionTimeout) << 平均故障間隔時間(MTBF)
  • 廣播時間指的是從一個服務器並行的發送 RPCs 給集羣中的其餘服務器並接收響應的平均時間;
  • 選舉超時時間就是選舉的超時時間限制
  • 平均故障間隔時間就是對於一臺服務器而言,兩次故障之間的平均時間。

選舉超時時間要大於廣播時間的緣由是,防止跟隨者由於還沒收到領導者的心跳,而從新選主。

選舉超時時間要小於MTBF的緣由是,防止選舉時,能正常工做的server沒有達到大多數。

對於廣播時間,通常在[0.5ms,20ms]之間,而平均故障間隔時間通常很是大,至少是按照月爲單位。所以,通常選舉超時時間通常選擇範圍爲[10ms,500ms]。所以,當領導者掛掉後,能在較短期內從新選主。

動畫演示 Raft

http://thesecretlivesofdata.c...

相關文章
相關標籤/搜索