Raft 協議學習筆記

犀利豆發表於2018-06-05

原文地址:www.xilidou.com/2018/06/04/…

好久沒有更新部落格了,最近研究了Raft 協議,談談自己對 Raft 協議的理解。希望這篇文章能夠幫助大家理解 Raft 論文

Raft 是什麼?

Raft 是一種分散式系統的一致性演算法。

在分散式系統中,我們需要讓一組機器作為一個整體向外界提供服務。由於在實際的條件下,我們認為每臺機器都是不100%可靠的,隨時都可能發生當機。每臺機器之間的通訊也不是可靠的,可能發生通訊的阻塞、丟失、重試。所以需要某些演算法來保證在大多數機器都正常的情況下向外提供可靠的服務。

在 Raft提出之前,Paxos 已經被提出,但是 Paxos 相當複雜。Raft 的目標就是提出一種易於理解的分散式一致性演算法。

在瞭解 Raft 之前需要了解一下什麼狀態機:

論文指出,Raft 是一種用來管理日誌複製的一致性演算法。所以我們就要先了解一下。什麼是日誌複製狀態機。我們思考一個問題。如果你要與你的小夥伴分享一個很複雜的操作及計算。一般來說你有兩種做法: 第一種:你自己負責計算,經過一段時間的計算,算出結果後,直接把計算結果告訴你的小夥伴。 第二種:你把每一個操作的步驟都告訴你的夥伴,告訴他怎麼做,由你的夥伴自己計算出結果。

第二種方式,就是複製狀態機的工作原理。複製狀態機是通過複製日誌來實現的。每一臺伺服器儲存著一份日誌,日誌中包含一系列的命令,狀態機會按順序執行這些命令。因為每一臺計算機的狀態機都是確定的,所以每個狀態機的狀態都是相同的,執行的命令是相同的,最後的執行結果也就是一樣的了。

在實際中這種有很多類似的應用比如 mysql 的主從同步就是通過 binlog 進行同步。

在現實生活中,如何有效的組織多人進行協助,最自然的想法就是選舉一個領導,交由領導極大的權威,就能極大的提升整個團隊工作效率。

下面就談談我對 Raft 演算法的理解。

基本安全保證:

為了保證過程正確性,Raft需要保證以下的性質時刻為真:

  • 選舉安全原則: 同一屆任期內至多隻能有一個領導人。

  • 領導人只加原則: 領導人的日誌只能增加,不能重寫或者刪除。

  • 日誌匹配原則: 如果兩個日誌具有相同的任期和索引,則這兩段日誌在[0,索引]之間的日誌完全相同。

  • 領導人完全原則: 如果一條日誌被提交,那麼後續的任意任期的領導人都會有這條日誌。

  • 狀態機安全原則: 如果一個伺服器已經將給定索引位置的日誌條目應用到狀態機中,則所有其他伺服器不會在該索引位置應用不同的條目。

選取領導者

所以 Raft 演算法成立的最重要的前提之一就是選舉。

  • Raft 由多個節點組成。
  • 強領導者, 整個 Raft 在同一時間,只有一個領導者,日誌有領導者負責分發和同步。
  • 領導選舉, 領導是由民主選舉產生的,叢集中多數節點投票通過就能成為主。

對於在叢集中的節點。在任意時間中,都有可能處於以下三種狀態之一:

  • 跟隨者
  • 候選人
  • 領導人

每個領導人都有一個任期限制。每一屆任期的開始階段,都是選舉。如果選舉出了領導者就由該領導人負責領導叢集。如果沒有選舉出領導,就會進入下一次選舉。直到選舉出領導者為止。

角色之間的轉換:

role

領導者會週期性的向每臺機器傳送心跳,確保自己的領導地位。

跟隨者在長時間沒有收到領導人的心跳,就會發起投票成為候選人,同時任期 + 1,如果獲得超過半數的支援,就升任為領導。

如果候選人,在發起投票的時候,發現叢集裡面有領導人的時候,就會重新成為追隨者。

如果候選人,發起投票後,一定時間裡面沒有收到超過半數的反饋,就會再次發起投票。

如果領導者發現在叢集中發現存在下一任期的領導者,就會變為追隨者。

日誌同步

在選舉出領導人以後,就開始處理客戶端的日誌。

領導者在收到客戶端的請求,每個請求包含一個操作的命令。領導者會將命令記錄到自己的日誌中,並向自己的追隨者發起同步的請求,要求自己的追隨者複製這個命令。

一旦這個命令被大多數的追隨者儲存了。領導者就認為這個狀態已經處於提交(commited)的狀態。同時告知客戶端,命令已經被提交。如果這個時候,追隨者發生了崩潰或者延時。領導者會一直嘗試重試,直到追隨者接受命令,並儲存到自己的日誌中。這個過程一直持續到所有的追隨者最終儲存了所有的日誌條目。

作為 Raft 的節點需要保證如下性質。

  • 如果在不同日誌中的兩個條目有著相同的索引和任期號,則它們所儲存的命令是相同的。
  • 如果在不同日誌中的兩個條目有著相同的索引和任期號,則它們之間的所有條目都是完全一樣的。

有了如上性質的保證。如果在某些情況下,發生了追隨者的日誌與領導者不同步的情況。(包括的情況,就可能是丟失日誌,或者儲存了領導者沒有的日誌,或者兩兼有),在 Raft 演算法中,領導人通過強制追隨者們複製它的日誌來處理日誌的不一致。這就意味著,在追隨者上的衝突日誌會被領導者的日誌覆蓋。

為了使得追隨者的日誌同自己的一致,領導人需要找到追隨者同它的日誌一致的地方,然後刪除追隨者在該位置之後的條目,然後將自己在該位置之後的條目傳送給追隨者。

安全分析

需要分析在各種情況下,每個角色發生當機,資料的安全性。

選舉限制

Raft 保證自己的日誌,永遠由領導者向追隨者流動。也就是說領導者永遠不會刪改自己的日誌,只能向上增加日誌。為了達成這個限制,Raft 使用投票的方式來阻止沒有包含全部日誌條目的伺服器贏得選舉。

當一個候選人發起投票的時候,需要告訴大家,自己最新的日誌。其他節點在投票的時候,要保證自己的日誌不能比候選人的新,否則就拒絕投票。通過這個限制就保證了獲取多數票的領導者的日誌,至少比大多數人要新。

任期越大,日誌越長,越容易成為領導者。

提交之前任期的日誌條目

erro

這個在論文中比較難以理解。我看到這一節的時候也是讀了好幾遍才理解論文的意思。實際上作者表達的意思是圖 (d)是正確的,而(e)是錯誤的。

因為 2 號日誌沒有commited,但是由於一系列操作,造成了 2 號日誌沒有提交,但是高任期的leader 卻認為 2 號日誌被提交了。

為了解決這個問題。Raft 限制,只有當前任期的 leader 可以決定一條日誌是否 commited,而不能由高任期的 leader 通過計算某條日誌(例子中的 2號日誌)超過半數節點持有,就確定日誌被commited。

換句話說,就是 Raft 限制每個leader 只能確定自己任期內的日誌是否commited。而不能由高任期的 leader確定。

追隨者和候選人崩潰

由於 Raft 是一個強領導的,少數服從多數的系統。上面花了了很多的篇幅討論 leader 奔潰後 Raft 協議是如何保證準確性和安全性的。如果追隨者或者候選人掛了,就比較簡單了。

如果候選人崩潰,一段時間以後,某個節點會出發超時,重新發起選舉,一切就回復正常了。

如果一個追隨者崩潰,會被 leader 感知。 leader 會一直重試,直到追隨者恢復,並同步所有日誌。

系統的擴容

分散式系統一大優勢就是能夠快速擴容。

Raft 為了保證擴容的安全性,採用了兩段two-phase)方法。

在Cold 和 Cnew 之間存在一箇中間態, Cold,new 的狀態。防止剛開始擴容的時候,新的一組機器數量大於老叢集數量,就有可能在新機器中自發投票選舉出一個 leader,造成叢集中有兩個leader形成腦裂。

  • 日誌條目被複制給叢集中新、老配置的所有伺服器。
  • 新、老配置的伺服器都能成為領導人。
  • 需要分別在兩種配置上獲得大多數的支援才能達成一致(針對選舉和提交)

需要解決三個問題:

  • 為了不拖慢整個叢集相應速度,可以不給新加入的節點投票權。知道日誌追齊以後再開放投票權力
  • 如果擴容以後,老的 leader 屬於被踢出的節點,老 leader 不會立即下線,而是繼續工作,直到 Cnew 被提交。這個時候 leader 自己只負責管理叢集而自己不追加日誌。
  • 將要被被刪除的節點,不會收到領導的心跳,就會不停的認為自己超時,會不斷的成為候選人,並不斷的發起投票。造成叢集的 leader 不斷的退位,然後再次產生 leader。造成叢集的響應能力降低。為了避免這個問題,當伺服器確認當前領導人存在時,伺服器會忽略請求投票。每個伺服器在開始一次選舉之前,至少等待一個最小選舉超時時間。

日誌的壓縮:

日誌的壓縮比較容易理解,隨著叢集的使用,日誌的數量越來越大,就會降低叢集的效能,同時佔用大量的儲存空間。所以需要定期對日誌進行壓縮。快照是最簡單的壓縮方法。在快照系統中,整個系統的狀態都以快照的形式寫入到穩定的持久化儲存中,然後到那個時間點之前的日誌全部丟棄。

客戶端互動

整個 Raft 協議中,客戶端只與 leader 進行互動。

客戶端與叢集通訊的時候,首先隨便與叢集中的任意一個節點互動,詢問 leader 是誰。

是客戶端對於每一條指令都賦予一個唯一的序列號。然後,狀態機跟蹤每條指令最新的序列號和相應的響應。如果接收到一條指令,它的序列號已經被執行了,那麼就立即返回結果,而不重新執行指令。這樣保證互動的命令是冪等的。如果一條命令被重複提交,並不會造成狀態機的錯誤。

對於讀取的命令來說,如領導人已經被廢黜,而自己不知道。就容易造成客戶端讀取到髒資料。最新的資料由別的 leader 維護了。為了避免這個問題:

  • 領導人必須擁有最新的資料,這一點是必然的。Raft 天然保證這個特性。
  • 領導人在訪問資料之前需要傳送一次心跳,保證自己的領導地位。

參考:

歡迎關注我的微信公眾號:

二維碼

相關文章