分佈式一致性算法(二)Raft算法

一、更加直觀的Raft算法

Raft 適用於一個管理日誌一致性的協議,相比於 Paxos 協議 Raft 更易於理解和去實現它。
爲了提高理解性,Raft 將一致性算法分爲了幾個部分,包括領導選取(leader selection)、日誌複製(log replication)、安全(safety),並且使用了更強的一致性來減少了必須需要考慮的狀態。

1.解決什麼問題

分佈式存儲系統通常通過維護多個副本來提高系統的availability,帶來的代價就是分佈式存儲系統的核心問題之一:維護多個副本的一致性。

Raft協議基於複製狀態機(replicated state machine),即一組server從相同的初始狀態起,按相同的順序執行相同的命令,最終會達到一直的狀態,一組server記錄相同的操作日誌,並以相同的順序應用到狀態機。

replicated state machine

Raft有一個明確的場景,就是管理複製日誌的一致性。

如圖,每臺機器保存一份日誌,日誌來自於客戶端的請求,包含一系列的命令,狀態機會按順序執行這些命令。
一致性算法管理來自客戶端狀態命令的複製日誌,保證狀態機處理的日誌中的命令的順序都是一致的,因此會得到相同的執行結果。

state machine

2.Raft概覽

先看一段動畫演示,Understandable Distributed Consensus 。

相比Paxos,Raft算法理解起來直觀的很。

Raft算法將Server劃分爲3種狀態,或者也可以稱作角色:

  • Leader

負責Client交互和log複製,同一時刻系統中最多存在1個。

  • Follower

被動響應請求RPC,從不主動發起請求RPC。

  • Candidate

一種臨時的角色,只存在於leader的選舉階段,某個節點想要變成leader,那麼就發起投票請求,同時自己變成candidate。如果選舉成功,則變爲candidate,否則退回爲follower

狀態或者說角色的流轉如下:

state

在Raft中,問題分解爲:領導選取、日誌複製、安全和成員變化。

複製狀態機通過複製日誌來實現:

  • 日誌:每臺機器保存一份日誌,日誌來自於客戶端的請求,包含一系列的命令
  • 狀態機:狀態機會按順序執行這些命令
  • 一致性模型:分佈式環境下,保證多機的日誌是一致的,這樣回放到狀態機中的狀態是一致的

 

二、Raft算法流程

Raft中使用心跳機制來出發leader選舉。當服務器啓動的時候,服務器成爲follower。只要follower從leader或者candidate收到有效的RPCs就會保持follower狀態。如果follower在一段時間內(該段時間被稱爲election timeout)沒有收到消息,則它會假設當前沒有可用的leader,然後開啓選舉新leader的流程。

1.Term

Term的概念類比中國歷史上的朝代更替,Raft 算法將時間劃分成爲任意不同長度的任期(term)。

任期用連續的數字進行表示。每一個任期的開始都是一次選舉(election),一個或多個候選人會試圖成爲領導人。如果一個候選人贏得了選舉,它就會在該任期的剩餘時間擔任領導人。在某些情況下,選票會被瓜分,有可能沒有選出領導人,那麼,將會開始另一個任期,並且立刻開始下一次選舉。Raft 算法保證在給定的一個任期最多隻有一個領導人。

中國歷史

2.RPC

Raft 算法中服務器節點之間通信使用遠程過程調用(RPCs),並且基本的一致性算法只需要兩種類型的 RPCs,爲了在服務器之間傳輸快照增加了第三種 RPC。

RPC有三種:

  • RequestVote RPC:候選人在選舉期間發起
  • AppendEntries RPC:領導人發起的一種心跳機制,複製日誌也在該命令中完成
  • InstallSnapshot RPC: 領導者使用該RPC來發送快照給太落後的追隨者

3.選舉流程

(1)follower增加當前的term,轉變爲candidate。
(2)candidate投票給自己,併發送RequestVote RPC給集羣中的其他服務器。
(3)收到RequestVote的服務器,在同一term中只會按照先到先得投票給至多一個candidate。且只會投票給log至少和自身一樣新的candidate。

candidate節點保持(2)的狀態,直到下面三種情況中的一種發生。

  • 該節點贏得選舉。即收到大多數的節點的投票。則其轉變爲leader狀態。
  • 另一個服務器成爲了leader。即收到了leader的合法心跳包(term值等於或大於當前自身term值)。則其轉變爲follower狀態。
  • 一段時間後依然沒有勝者。該種情況下會開啓新一輪的選舉。

Raft中使用隨機選舉超時時間來解決當票數相同無法確定leader的問題。

4.日誌複製

日誌複製(Log Replication)主要作用是用於保證節點的一致性,這階段所做的操作也是爲了保證一致性與高可用性。

當Leader選舉出來後便開始負責客戶端的請求,所有事務(更新操作)請求都必須先經過Leader處理,日誌複製(Log Replication)就是爲了保證執行相同的操作序列所做的工作。

在Raft中當接收到客戶端的日誌(事務請求)後先把該日誌追加到本地的Log中,然後通過heartbeat把該Entry同步給其他Follower,Follower接收到日誌後記錄日誌然後向Leader發送ACK,當Leader收到大多數(n/2+1)Follower的ACK信息後將該日誌設置爲已提交併追加到本地磁盤中,通知客戶端並在下個heartbeat中Leader將通知所有的Follower將該日誌存儲在自己的本地磁盤中。

三、Raft和Paxos的工程應用

Raft算法的論文相比Paxos直觀很多,更容易在工程上實現。

可以看到Raft算法的實現已經非常多了,https://raft.github.io/#implementations

1.Raft的應用

這裏用ETCD來關注Raft的應用,ETCD目標是構建一個高可用的分佈式鍵值(key-value)數據庫,基於 Go 語言實現。
Etcd 主要用途是共享配置和服務發現,實現一致性使用了Raft算法。
更多Etcd的應用可以查看文檔:https://coreos.com/etcd/docs/latest/

2.Zookeeper 中的 Paxos

Zookeeper 使用了一種修改後的 Paxos 協議。

在 Zookeeper 中,始終分爲兩種場景:

  • Leader activation

在這個場景裏,系統中缺乏 Leader(primary),通過一個類似 paxos 協議的過程完成 Leader 選舉。

  • Active messaging
    在 這個場景裏,Leader 接收客戶端發送的更新操作,以一種類似兩階段提交的過程在各個 follower (secondary)節點上進行更新操作。

在 Leader activation 場景中完成 leader 選舉及數據同步後,系統轉入 Active messaging 場景,在 active messaging 中 leader 異常後,系統轉入 Leader activation 場景。

無論在那種場景,Zookeeper 依賴於一個全局版本號:zxid。zxid 由(epoch, count)兩部分組成, 高位的 epoch 部分是選舉編號,每次提議進行新的 leader 選舉時 epoch 都會增加,低位的 count 部分 是 leader 爲每個更新操作決定的序號。可以認爲,一個 leader 對應一個唯一的 epoch,每個 leader 任期內產生的更新操作對應一個唯一的有序的 count,從而從全局的視野,一個 zxid 代表了一個更新操作的全局序號(版本號)。

Zookeeper 通過 zxid 將兩個場景階段較好的結合起來,且能保證全局的強一致性。由於同一時刻只有一個 zookeeper 節點能獲得超過半數的 follower,所以同一時刻最多隻存在唯一的 leader;每個 leader 利用 FIFO 以 zxid 順序更新各個 follower,只有成功完成前一個更新操作的纔會進行下一個更新操作,在同一個 leader 任期內,數據在全局滿足 quorum 約束的強一致,即讀超過半數的節點 一定可以讀到最新已提交的數據;每個成功的更新操作都至少被超過半數的節點確認,使得新選舉 的 leader 一定可以包括最新的已成功提交的數據。

3.如何解決split brain問題

分佈式協議一個著名問題就是 split brain 問題。

簡單說,就是比如當你的 cluster 裏面有兩個結點,它們都知道在這個 cluster 裏需要選舉出一個 master。那麼當它們兩之間的通信完全沒有問題的時候,就會達成共識,選出其中一個作爲 master。但是如果它們之間的通信出了問題,那麼兩個結點都會覺得現在沒有 master,所以每個都把自己選舉成 master。於是 cluster 裏面就會有兩個 master。

區塊鏈的分叉其實類似分佈式系統的split brain。

一般來說,Zookeeper會默認設置:

  • zookeeper cluster的節點數目必須是奇數。
  • zookeeper 集羣中必須超過半數節點(Majority)可用,整個集羣才能對外可用。

Majority 就是一種 Qunroms 的方式來支持Leader選舉,可以防止 split brain出現。奇數個節點可以在相同容錯能力的情況下節省資源。

四、從CAP的角度理解幾種不同的算法

1.兩階段提交協議

兩階段提交系統具有完全的C,很糟糕的A,很糟糕的P。
首先,兩階段提交協議保證了副本間是完全一致的,這也是協議的設計目的。再者,協議在一個節點出現異常時,就無法更新數據,其服務可用性較低。最後,一旦協調者與參與者之間網絡分化,無法提供服務。

2.Paxos和Raft算法

Paxos 協議和Raft算法都是強一致性協議。Paxos只有兩種情況下服務不可用:一是超過半數的 Proposer 異常,二是出現活鎖。前者可以通過增加 Proposer 的個數來 降低由於 Proposer 異常影響服務的概率,後者本身發生的概率就極低。最後,只要能與超過半數的 Proposer 通信就可以完成協議流程,協議本身具有較好的容忍網絡分區的能力。

參考
Raft一致性算法
Raft 一致性算法論文譯文

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章