從分散式一致性到共識機制(二)Raft演算法
春秋五霸說開
春秋五霸,是指東周春秋時期相繼稱霸主的五個諸侯,“霸”,意為霸主,即是諸侯之領袖。
典型的比如齊桓公,晉文公,春秋時期諸侯國的稱霸,與今天要討論的Raft演算法很像。
一、更加直觀的Raft演算法
Raft 適用於一個管理日誌一致性的協議,相比於 Paxos 協議 Raft 更易於理解和去實現它。
為了提高理解性,Raft 將一致性演算法分為了幾個部分,包括領導選取(leader selection)、日誌複製(log replication)、安全(safety),並且使用了更強的一致性來減少了必須需要考慮的狀態。
1.解決什麼問題
分散式儲存系統通常通過維護多個副本來提高系統的availability,帶來的代價就是分散式儲存系統的核心問題之一:維護多個副本的一致性。
Raft協議基於複製狀態機(replicated state machine),即一組server從相同的初始狀態起,按相同的順序執行相同的命令,最終會達到一直的狀態,一組server記錄相同的操作日誌,並以相同的順序應用到狀態機。
Raft有一個明確的場景,就是管理複製日誌的一致性。
如圖,每臺機器儲存一份日誌,日誌來自於客戶端的請求,包含一系列的命令,狀態機會按順序執行這些命令。
一致性演算法管理來自客戶端狀態命令的複製日誌,保證狀態機處理的日誌中的命令的順序都是一致的,因此會得到相同的執行結果。
2.Raft概覽
先看一段動畫演示,Understandable Distributed Consensus 。
相比Paxos,Raft演算法理解起來直觀的很。
Raft演算法將Server劃分為3種狀態,或者也可以稱作角色:
- Leader
負責Client互動和log複製,同一時刻系統中最多存在1個。
- Follower
被動響應請求RPC,從不主動發起請求RPC。
- Candidate
一種臨時的角色,只存在於leader的選舉階段,某個節點想要變成leader,那麼就發起投票請求,同時自己變成candidate。如果選舉成功,則變為candidate,否則退回為follower
狀態或者說角色的流轉如下:
在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演算法
- 區塊鏈共識演算法(1)分散式一致性演算法Raft區塊鏈演算法分散式Raft
- kafka和raft共識機制KafkaRaft
- 深入剖析分散式一致性共識演算法分散式演算法
- tikv/raft-rs:在 Rust 中實現的 Raft 分散式共識演算法原始碼RaftRust分散式演算法原始碼
- zarusz/SlimCluster:在.NET中實現的Raft分散式共識演算法Raft分散式演算法
- 分散式共識演算法分散式演算法
- 理解分散式一致性與Raft演算法分散式Raft演算法
- 淺談分散式一致性演算法raft分散式演算法Raft
- Raft共識演算法詳解Raft演算法
- 區塊鏈共識演算法(4)分散式一致性演算法Paxos區塊鏈演算法分散式
- 深入剖析共識性演算法 Raft演算法Raft
- 搞懂分散式技術2:分散式一致性協議與Paxos,Raft演算法分散式協議Raft演算法
- 讀懂區塊鏈共識機制 :PoW、PoS、PAXOS、RAFT、PBFT區塊鏈Raft
- 分散式強一致性資料庫的靈魂 - Raft 演算法分散式資料庫Raft演算法
- 分散式強一致性資料庫的靈魂 – Raft 演算法分散式資料庫Raft演算法
- 分散式系統的Raft演算法分散式Raft演算法
- 4.0體驗站|OceanBase 4.0,從分散式到單機,從單機到分散式分散式
- 分散式理論(六) - 一致性協議Raft分散式協議Raft
- 分散式協議與演算法-Raft演算法分散式協議演算法Raft
- 區塊鏈共識演算法(6)分散式一致性演算法2PC和3PC區塊鏈演算法分散式
- 分散式系統架構1:共識演算法Paxos分散式架構演算法
- 分散式共識如何運作?分散式
- 共識演算法之爭(PBFT,Raft,PoW,PoS,DPoS,Ripple)演算法Raft
- 區塊鏈知識系列 - Raft 共識區塊鏈Raft
- 幽默!分散式系統共識演算法的三階段分散式演算法
- NEO共識機制圖解圖解
- NEO共識機制白皮書
- 區塊鏈共識機制區塊鏈
- 基於hashicorp/raft的分散式一致性實戰教學Raft分散式
- 分散式一致性協議Raft全面詳解(建議收藏)分散式協議Raft
- 分散式鎖機制分散式
- 深入理解分散式系統:分割槽、複製、分散式事務以及系統一致性與共識分散式
- 區塊鏈共識機制技術一--POW(工作量證明)共識機制區塊鏈
- 以太坊的POS共識機制
- 一致性協議淺析:從邏輯時鐘到Raft協議Raft
- paxos分散式一致性演算法分散式演算法
- Paxos——分散式一致性演算法分散式演算法