raft共識算法

raft共識算法

分佈式一致性問題算法

若是說,服務器只有一個節點,那麼,要保證一致性,沒有任何問題,由於全部讀寫都在一個節點上發生。那若是server端有2個、3個甚至更多節點,要怎麼達成一致性呢?下面就來介紹其中一種分佈式共識算法---raft算法數據庫

Raft是什麼安全

1.歷史背景服務器

在講Raft前,有必要提一下Paxos算法,Paxos算法是Leslie Lamport於1990年提出的基於消息傳遞的一致性算法。然而,因爲算法難以理解,剛開始並無獲得不少人的重視。其後,做者在八年後,也就是1998年在ACM上正式發表,然而因爲算法難以理解仍是沒有獲得重視。而做者以後用更容易接受的方法從新發表了一篇論文《Paxos Made Simple》。網絡

可見,Paxos算法是有多難理解,即使如今放到不少高校,依然不少學生、教授都反饋Paxos算法難以理解。同時,Paxos算法在實際應用實現的時候也是比較困難的。這也是爲何會有後來Raft算法的提出。架構

2.概念併發

Raft是實現分佈式共識的一種算法,主要用來管理日誌複製的一致性。它和Paxos的功能是同樣,可是相比於Paxos,Raft算法更容易理解、也更容易應用到實際的系統當中。而Raft算法也是聯盟鏈採用比較多的共識算法。分佈式

備註:區塊鏈分爲:公有鏈、聯盟鏈和私有鏈區塊鏈

Raft的三種狀態(角色)3d

Follower(羣衆)

被動接收Leader發送的請求。全部的節點剛開始的時候是處於Follower狀態。

Candidate(候選人)

由Follower向Leader轉換的中間狀態

Leader(領導)

負責和客戶端交互以及日誌複製(日誌複製是單向的,即Leader發送給Follower),同一時刻最多隻有1個Leader存在。

三種狀態的轉換關係以下,下一節的Raft工做機制會具體講到。

 

幾個關鍵概念

一、複製狀態機

咱們知道,在一個分佈式系統數據庫中,若是每一個節點的狀態一致,每一個節點都執行相同的命令序列,那麼最終他們會獲得一個一致的狀態。也就是和說,爲了保證整個分佈式系統的一致性,咱們須要保證每一個節點執行相同的命令序列,也就是說每一個節點的日誌要保持同樣。因此說,保證日誌複製一致就是Raft等一致性算法的工做了。

 

複製狀態機架構

這裏就涉及Replicated State Machine(複製狀態機),如上圖所示。在一個節點上,一致性模塊(Consensus Module,也就是分佈式共識算法)接收到了來自客戶端的命令。而後把接收到的命令寫入到日誌中,該節點和其餘節點經過一致性模塊進行通訊確保每一個日誌最終包含相同的命令序列。一旦這些日誌的命令被正確複製,每一個節點的狀態機(State Machine)都會按照相同的序列去執行他們,從而最終獲得一致的狀態。而後將達成共識的結果返回給客戶端,以下圖所示。

 

二、任期(Term)概念

在分佈式系統中,「時間同步」是一個很大的難題,由於每一個機器可能因爲所處的地理位置、機器環境等因素會不一樣程度形成時鐘不一致,可是爲了識別「過時信息」,時間信息必不可少。

Raft算法中就採用任期(Term)的概念,將時間切分爲一個個的Term(同時每一個節點自身也會本地維護currentTerm),能夠認爲是邏輯上的時間,以下圖。

 

每一任期的開始都是一次領導人選舉,一個或多個候選人(Candidate)會嘗試成爲領導(Leader)。若是一我的贏得選舉,就會在該任期(Term)內剩餘的時間擔任領導人。在某些狀況下,選票可能會被評分,有可能沒有選出領導人(如t3),那麼,將會開始另外一任期,而且理科開始下一次選舉。Raft 算法保證在給定的一個任期最少要有一個領導人。

三、心跳(heartbeats)和超時機制(timeout)

在Raft算法中,有兩個timeout機制來控制領導人選舉:

一個是選舉定時器(eletion timeout):即Follower等待成爲Candidate狀態的等待時間,這個時間被隨機設定爲150ms~300ms之間

另外一個是headrbeat timeout:在某個節點成爲Leader之後,它會發送Append Entries消息給其餘節點,這些消息就是經過heartbeat timeout來傳送,Follower接收到Leader的心跳包的同時也重置選舉定時器。

 

Raft的工做機制

Raft算法能夠分爲以下3個部分:

一、領導人選舉(Leader Election)

(1)一開始,全部節點都是以Follower角色啓動,同時啓動選舉定時器(時間隨機,下降衝突機率)

 

(2)若是一個節點發如今超過選舉定時器的時間之後一直沒有收到Leader發送的心跳請求,則該節點就會成爲候選人,而且一直處於該狀態,直到下列三種狀況之一發生:

該節點(Candidate)贏得選舉

其餘節點贏得選舉

一段時間後沒有任何一臺服務器贏得選舉(進入下一輪Term的選舉,並隨機設置選舉定時器時間)

 

(3)而後這個候選人就會向其餘節點發送投票請求(Request Vote),若是獲得半數以上節點的贊成,就成爲Leader(Leader)。若是選舉超時,尚未Leader選出,則進入下一任期,從新選舉。

 

(4)完成Leader選舉後,Leader就會定時給其餘節點發送心跳包(Heartbeat),告訴其餘節點Leader還在運行,同時重置這些節點的選舉定時器。

二、日誌複製(Log Replication)

(1)Client向Leader提交指令(如:SET 5),Leader收到命令後,將命令追加到本地日誌中。此時,這個命令處於「uncomitted」狀態,複製狀態機不會執行該命令。

 

(2)而後,Leader將命令(SET 5)併發複製給其餘節點,並等待其餘其餘節點將命令寫入到日誌中,若是此時有些節點失敗或者比較慢,Leader節點會一直重試,知道全部節點都保存了命令到日誌中。以後Leader節點就提交命令(即被狀態機執行命令,這裏是:SET 5),並將結果返回給Client節點。

 

(3)Leader節點在提交命令後,下一次的心跳包中就帶有通知其餘節點提交命令的消息,其餘節點收到Leader的消息後,就將命令應用到狀態機中(State Machine),最終每一個節點的日誌都保持了一致性。

 

Leader節點會記錄已經交的最大日誌index,以後後續的heartbeat和日誌複製請求(Append Entries)都會帶上這個值,這樣其餘節點就知道哪些命令已經提交了,就可讓狀態機(State Machine)執行日誌中的命令,使得全部節點的狀態機數據都保持一致。

下面咱們來看下日誌內容不一致的狀況下,Raft算法如何處理?

以下圖,若是在一個分佈式網絡中,各個節點的日誌狀態以下。當Leader節點發送日誌複製請求的時,它會帶上上一次的日誌記錄的index和term。

此時Leader節點發送日誌複製請求。此時,A節點收到Leader的請求後,對比Leader節點記錄的上一個日誌記錄的index和term,發現:

index(leader)> index(A)

term(leader)> currentTerm(A)

發現本身的日誌中不存在這個命令,因而拒絕這個請求。此時,Leader節點知道發生了不一致,因而遞減nextIndex,並從新給A節點發送日誌複製請求,直到找到日誌一致的地方爲止。而後把Follower節點的日誌覆蓋爲Leader節點的日誌內容。

也就是說,Raft算法對於日誌內容不一致的請求,會採起Leader節點的日誌內容覆蓋Follower節點的日誌內容的作法,先找到二者日誌記錄第一次不一致的地方,而後一直覆蓋到最新提交的命令位置。

 

三、安全性

以前的內容討論了 Raft 算法是如何進行領導選取和複製日誌的。然而,到目前爲止這個機制還不能保證每個狀態機能按照相同的順序執行一樣的指令。例如,當領導人提交了若干日誌條目的同時一個追隨者可能宕機了,以後它又被選爲了領導人而後用新的日誌條目覆蓋掉了舊的那些,最後,不一樣的狀態機可能執行不一樣的命令序列。

而Raft算法經過在領導人選舉階段增長一個限制來完善了Raft算法。這個限制能保證,對於固定任期,任何領導人都擁有以前任期提交的所有日誌命令。Raft算法經過投票的方式來阻止那些沒有包含所有日誌命令的節點贏得選舉。

一個Candidate節點要成爲贏得選舉,就須要跟網絡中大部分節點進行通訊,這就意味着每一條已經提交的日誌條目最少在其中一臺服務器上出現。若是候選人的日誌至少和大多數服務器上的日誌同樣新,那麼它必定包含有所有的已經提交的日誌條目。RequestVote RPC 實現了這個限制:這個 RPC包括候選人的日誌信息,若是它本身的日誌比候選人的日誌要新,那麼它會拒絕候選人的投票請求。

那麼,怎麼判斷兩個節點日誌內容比較新呢?其標準以下,Raft算法經過比較日誌中最後一個命令的索引(index)和任期號(term)來斷定哪個日誌內容比較新。

若是兩個日誌的任期號不一樣,任期號大的日誌內容更新

若是任期號相同,日誌長的日誌內容更新

實例分析

下面咱們來考慮一個比較極端的狀況,出現網絡分區的時候,Raft如何保持一致性。

以下圖,咱們將分佈式網絡分割爲兩個子網,分別是子網絡AB和子網絡CDE,此時節點B是Leader節點。

 

然而因爲網絡分區致使子網1不存在Leader節點,此時,C、D和E節點因爲沒有收到Leader節點的心跳,致使選舉定時器超時從而進入Candidate狀態,開始進行領導人選舉。

 

這時,咱們假設C節點贏得選舉,成爲子網1的Leader節點。

 

此時,若是兩個子網有Client節點分別向各個子網的Leader節點提交數據(如:X←3),因爲子網2中Leader節點B不可能複製到大部分節點,因此其X←3命令會一直處於「uncomitted」狀態。而子網1因爲成功複製給大部分節點,因此X←3最終在子網1達成共識,以下圖所示。

 

咱們假設,子網1通過屢次選舉和數據交互,最終子網1的日誌狀態以下圖所示:

 

而此時,分區隔離狀態消失。Leader C和Leader B分別會發送心跳請求,最終Leader B發現Leader C選票比本身更多,從而轉換爲Follower狀態。而經過日誌複製(Log Replication),最終全部節點日誌達成一直,以下圖。

 

 
  • 原文連接:https://kuaibao.qq.com/s/20180525G06G5O00?refer=cp_1026
相關文章
相關標籤/搜索