分散式理論(六) - 一致性協議Raft

零壹技術棧發表於2018-06-17

前言

Raft 也是一個 一致性演算法,和 Paxos 目標相同。但它還有另一個名字 - 易於理解的一致性演算法PaxosRaft 都是為了實現 一致性 產生的。這個過程如同選舉一樣,參選者 需要說服 大多數選民 (伺服器) 投票給他,一旦選定後就跟隨其操作。PaxosRaft 的區別在於選舉的 具體過程 不同。

正文

小試牛刀

在進入正題前,給大家分享一個《數學發散思維》中的一個故事,站在不同思維角度上,瞭解對一個問題理解的差異性。

問題: 甲乙兩人輪流在一張圓桌上平放黑白圍棋子,每次放一子,棋子不許重疊,誰先沒有地方放就輸。請問怎樣放才能贏?

這個問題有兩層意思,第一,有沒有一種放法保證必贏?第二,如果有怎麼證明?

分散式理論(六) - 一致性協議Raft

上圖回答了這個問題,那就是先行者必勝,這裡使用了三種不同的思維方式來闡述:

  1. 假如桌子只有一個圍棋子那麼大。

  2. 假如桌子無限大,先行者先佔住圓心。由於圓是對稱圖形,所以只要對手還能找到位置放,你總能在對稱的另一面找到位置放。

  3. 一個圓中可畫單數個直徑相等且互切的小圓。

三種不同的思維方式在可理解性難度上逐漸加深。

  1. 第一種是 極簡化思維,但數學上是 不嚴謹 的。

  2. 第二種是 極限思維,和第一種結合起來就是 數學歸納法,在數學上是 嚴謹 的。

  3. 第三種是 形象思維,使用了 幾何學概念,但對於沒有幾何學基礎知識的人就很難理解了。

什麼是Raft協議

Raft 協議將 Server 程式分成三類,分別是 LeaderCandidateFollower。一個 Server 程式在某一時刻,只能是其中 一種型別,但這不是固定的。不同的時刻,它可能擁有不同的型別,一個 Server 程式的型別是如何改變的,後面會有解釋。

在一個由 Raft 協議組織的叢集中有三類角色:

  • Leader(領袖)
  • Follower(群眾)
  • Candidate(候選人)

就像一個民主社會,領袖由民眾投票選出。剛開始沒有 領袖,所有叢集中的 參與者 都是 群眾,那麼首先開啟一輪大選。在大選期間 所有群眾 都能參與競選,這時所有群眾的角色就變成了 候選人,民主投票選出領袖後就開始了這屆領袖的任期,然後選舉結束,所有除 領袖候選人 又變回 群眾角色 服從領袖領導。

這裡提到一個概念 「任期」,用術語 Term 表達。關於 Raft 協議的核心概念和術語就這麼多,而且和現實民主制度非常匹配,所以很容易理解。

三類角色的變遷圖如下,結合後面的選舉過程來看很容易理解。

分散式理論(六) - 一致性協議Raft

Leader選舉過程

在極簡的思維下,一個最小的 Raft 民主叢集需要 三個參與者(如下圖:ABC),這樣才可能投出多數票。

初始狀態 ABC 都是 Follower,然後發起選舉這時有 三種 可能的情形發生。下圖中前二種都能選出 Leader,第三種則表明 本輪投票無效Split Votes)。對於第三種,每方都投給了自己,結果沒有任何一方獲得多數票。之後 每個參與方 隨機休息一陣(Election Timeout)重新發起投票直到一方獲得多數票。這裡的關鍵就是隨機 timeout,最先從 timeout 中恢復發起投票的一方,向還在 timeout 中的另外兩方 請求投票,這時它就只能投給自己,導致很快達成一致。

分散式理論(六) - 一致性協議Raft

選出 Leader 後,Leader 通過 定期 向所有 Follower 傳送 心跳資訊 維持其統治。若 Follower 一段時間未收到 Leader心跳,則認為 Leader 可能已經掛了,然後再次發起 選舉 過程。

Leader對一致性的影響

Raft 協議 強依賴 Leader 節點的 可用性,以確保叢集 資料的一致性資料的流向 只能從 Leader 節點向 Follower 節點轉移。具體過程如下:

分散式理論(六) - 一致性協議Raft

  1. Client 向叢集 Leader 節點 提交資料 後,Leader 節點 接收到的資料 處於 未提交狀態Uncommitted)。

  2. 接著 Leader 節點會 併發地 向所有 Follower 節點 複製資料等待接收響應

  3. 叢集中至少 超過半數 的節點 已接收 到資料後, Leader 再向 Client 確認資料 已接收

  4. 一旦向 Client 發出資料接收 Ack 響應後,表明此時 資料狀態 進入 已提交Committed),Leader 節點再向 Follower 節點發通知告知該 資料狀態已提交

在這個過程中,主節點 可能在 任意階段 掛掉,看下 Raft 協議如何針對不同階段保障 資料一致性 的。

1. 情形1

資料到達 Leader 節點前,這個階段 Leader 掛掉不影響一致性,不用多說。

分散式理論(六) - 一致性協議Raft

2. 情形2

資料到達 Leader 節點,但未複製到 Follower 節點。

這個階段 Leader 掛掉,資料屬於 未提交狀態Client 不會收到 Ack 會認為 超時失敗 可安全發起 重試

分散式理論(六) - 一致性協議Raft

Follower 節點上沒有該資料,重新選主Client 重試 重新提交 可成功。原來的 Leader 節點 恢復 後作為 Follower 加入叢集,重新從 當前任期 的新 Leader同步資料,強制保持和 Leader 資料一致

3. 情形3

資料到達 Leader 節點,成功複製到 Follower 所有節點,但 Follower 還未向 Leader 響應接收。

這個階段 Leader 掛掉,雖然資料在 Follower 節點處於 未提交狀態Uncommitted),但是 保持一致 的。重新選出 Leader 後可完成 資料提交

分散式理論(六) - 一致性協議Raft

此時 Client 由於不知到底提交成功沒有,可重試提交。針對這種情況 Raft 要求 RPC 請求實現 冪等性,也就是要實現 內部去重機制

4. 情形4

資料到達 Leader 節點,成功複製到 Follower 的部分節點,但這部分 Follower 節點還未向 Leader 響應接收。

這個階段 Leader 掛掉,資料在 Follower 節點處於 未提交狀態Uncommitted)且 不一致

分散式理論(六) - 一致性協議Raft

Raft 協議要求投票只能投給擁有 最新資料 的節點。所以擁有最新資料的節點會被選為 Leader,然後再 強制同步資料 到其他 Follower,保證 資料不會丟失最終一致

5. 情形5

資料到達 Leader 節點,成功複製到 Follower 所有或多數節點,資料在 Leader 處於已提交狀態,但在 Follower 處於未提交狀態。

這個階段 Leader 掛掉,重新選出 新的 Leader 後的處理流程和階段 3 一樣。

分散式理論(六) - 一致性協議Raft

6. 情形6

資料到達 Leader 節點,成功複製到 Follower 所有或多數節點,資料在所有節點都處於已提交狀態,但還未響應 Client。

這個階段 Leader 掛掉,叢集內部資料其實已經是 一致的Client 重複重試基於冪等策略對 一致性無影響

分散式理論(六) - 一致性協議Raft

7. 情形7

網路分割槽導致的腦裂情況,出現雙 Leader 的現象。

網路分割槽 將原先的 Leader 節點和 Follower 節點分隔開,Follower 收不到 Leader心跳重新 發起選舉產生新的 Leader,這時就產生了 雙Leader 現象。

分散式理論(六) - 一致性協議Raft

原先的 Leader 獨自在一個區,向它提交資料不可能複製到多數節點所以永遠提交不成功。向新的 Leader 提交資料可以提交成功。

網路恢復 後,舊的 Leader 發現叢集中有 更新任期Term)的新 Leader ,則 自動降級Follower 並從新 Leader同步資料 達成叢集 資料一致

驗證結果

綜上窮舉分析了 最小叢集3 節點)面臨的所有情況,可以看出 Raft 協議都能很好的應對 一致性問題,並且很容易理解。

小結

Paxos 演算法是 Leslie Lamport1990 年就公開發表在了自己的網站上,想想我們是什麼時候才聽說的?什麼時候才有一個可用的實現?而 Raft 演算法是 2013 年發表的,大家在參考 Raft開源實現庫,可以看到有很多基於不同語言的 開源實現庫,這就是 可理解性 的重要性。

相關連結

  1. 分散式理論(一) - CAP定理
  2. 分散式理論(二) - BASE理論
  3. 分散式理論(三) - 2PC協議
  4. 分散式理論(四) - 3PC協議
  5. 分散式理論(五) - 一致性演算法Paxos
  6. 分散式理論(六) - 一致性協議Raft

歡迎關注公眾號: 零壹技術棧

image

本帳號將持續分享後端技術乾貨,包括虛擬機器基礎,多執行緒程式設計,高效能框架,非同步、快取和訊息中介軟體,分散式和微服務,架構學習和進階等學習資料和文章。

相關文章