分佈式一致性之Raft算法

最近工作中用到了Consul,在學習過程中,發現它是基於Raft來做分佈式一致性的。正巧以前學習過Raft, 那麼就正好藉此機會複習一下吧!

Raft算法

有一個網站用動畫的形式生動的描述了Raft算法: Raft算法動畫演示 , 如果你跟着這個動畫過一遍,相信你很容易能理解它。

以下是我基於這個動畫以及一些別的文章(最後有列出),對Raft算法的一些整理, 如果你還不瞭解Raft,建議你先看看這個動畫。

Raft算法中的關鍵詞

Log

在Raft集羣中,主要的工作單元就是log entry(你可以認爲是對狀態的修改, 比如set X = 3)。

分佈式一致性問題可以被分解爲log的複製。我們稱一串log entry爲一個log。如果集羣中的所有成員都贊同log entries以及它們的順序,那麼我們認爲這個log是一致的。

有限狀態機

有限狀態機是有限個狀態以及狀態之間的轉移的集合。當新的log被應用(即修改集羣狀態),狀態機會在狀態間進行轉移。同一個log序列必須產生同樣的狀態。

節點集

節點集是所有參與到log複製的成員的總集。

法定個數

法定個數是一個節點集的大多數成員的個數。對於一個n個節點的集羣而言,法定個數需要值多少(n/2)+1個成員。

比如說,如果節點集有5個成員,法定個數至少是3。如果法定個數的節點處於不可用狀態,那麼整個集羣都將處於不可用狀態,任何新的log都不能被提交。

已提交的log

如果一個log entry被持久地保存到了法定個數的節點上,那麼稱這個log entry已經被提交了。當log entry被提交時,它可以被應用。

領導人

在任何時間,節點集都會選出一個節點來做領導人。領導人負責接收新的log entry,把它複製到follower上,管理它的提交和應用。

Raft集羣中每個節點的角色

每個節點可能的角色

  1. Leader
  2. Follower
  3. Candidate

節點角色的變化

有三個節點A,B, C。

每個節點初始時,都是Follower。 Follower經過一段時間還沒有收到來自Leader的信息(因爲這時候還沒有Leader), 這時候角色變成Candidate。

A, B變成了Candidate,C還處於Follower狀態。

Candidate會通過向其他節點請求投票的方式發起選舉, 得到大多數票的Candidate會變成Leader。

A,B都向其他兩個節點發起投票請求, 假設C投給了A, 這樣A就變成了Leader。

前面這個過程叫做領導人選舉

節點的狀態變化可以用下圖概括:

這裏寫圖片描述

數據的一致性

數據流向

Raft 協議強依賴 Leader 節點的可用性來確保集羣數據的一致性。數據的流向只能從 Leader 節點向 Follower 節點轉移。

當 Client 向集羣 Leader 節點提交數據後,Leader 節點接收到的數據處於未提交狀態(Uncommitted),接着 Leader 節點會併發向所有 Follower 節點複製數據並等待接收響應,確保至少集羣中超過半數節點已接收到數據後再向 Client 確認數據已接收。一旦向 Client 發出數據接收 Ack 響應後,表明此時數據狀態進入已提交(Committed),Leader 節點再向 Follower 節點發通知告知該數據狀態已提交。

這裏寫圖片描述

異常情況處理

假設集羣有兩個網絡分區, A屬於分區1, B,C屬於分區2。原本兩個分區之間是可以通信的,並且A是整個集羣的Leader。

這時候分區間的通信被隔斷了,於是B,C收不到 Leader A的心跳將發起選舉產生新的 Leader,假設是B。

這時候有兩個Leader,原先的 Leader A獨自在一個區,向它提交數據不可能複製到多數節點所以永遠提交不成功。而向新的 Leader B提交數據可以提交成功。

網絡恢復後A發現集羣中有更新任期(Term)的Leader B則自動降級爲 Follower 並從新 Leader 處同步數據達成集羣數據一致。

這裏寫圖片描述

參考:

  1. http://thesecretlivesofdata.com/raft/
  2. https://www.consul.io/docs/internals/consensus.html
  3. http://www.cnblogs.com/mindwind/p/5231986.html
發佈了123 篇原創文章 · 獲贊 334 · 訪問量 52萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章