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

前言

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

正文

小試牛刀

在進入正題前,給你們分享一個《數學發散思惟》中的一個故事,站在不一樣思惟角度上,瞭解對一個問題理解的差別性。github

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

這個問題有兩層意思,第一,有沒有一種放法保證必贏?第二,若是有怎麼證實?編程

上圖回答了這個問題,那就是先行者必勝,這裏使用了三種不一樣的思惟方式來闡述:後端

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

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

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

三種不一樣的思惟方式在可理解性難度上逐漸加深。網絡

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

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

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

什麼是Raft協議

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

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

  • Leader(領袖)
  • Follower(羣衆)
  • Candidate(候選人)

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

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

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

Leader選舉過程

在極簡的思惟下,一個最小的 Raft 民主集羣須要 三個參與者(以下圖:ABC),這樣纔可能投出多數票。

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

選出 Leader 後,Leader 經過 按期 向全部 Follower 發送 心跳信息 維持其統治。若 Follower 一段時間未收到 Leader心跳,則認爲 Leader 可能已經掛了,而後再次發起 選舉 過程。

Leader對一致性的影響

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

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

  2. 接着 Leader 節點會 併發地 向全部 Follower 節點 複製數據等待接收響應

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

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

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

1. 情形1

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

2. 情形2

數據到達 Leader 節點,但未複製到 Follower 節點。

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

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

3. 情形3

數據到達 Leader 節點,成功複製到 Follower 全部節點,但 Follower 還未向 Leader 響應接收。

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

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

4. 情形4

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

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

Raft 協議要求投票只能投給擁有 最新數據 的節點。因此擁有最新數據的節點會被選爲 Leader,而後再 強制同步數據 到其餘 Follower,保證 數據不會丟失最終一致

5. 情形5

數據到達 Leader 節點,成功複製到 Follower 全部或多數節點,數據在 Leader 處於已提交狀態,但在 Follower 處於未提交狀態。

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

6. 情形6

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

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

7. 情形7

網絡分區致使的腦裂狀況,出現雙 Leader 的現象。

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

原先的 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

本賬號將持續分享後端技術乾貨,包括虛擬機基礎,多線程編程,高性能框架,異步、緩存和消息中間件,分佈式和微服務,架構學習和進階等學習資料和文章。

相關文章
相關標籤/搜索