分佈式系統——Raft的分析

這是一篇來自研究生一年級的課程—— 《分佈式系統》 的作業記錄博客。
其主要是實現分佈式系統中一致性的算法 Raft

論文鏈接如下:Raft算法英文原文地址
而中文翻譯地址如下:中文翻譯版本

首先我們大致通過一個動畫過程來了解一下Raft。鏈接如下:Raft動畫演示


1 分佈式系統的一致性問題

我們假設有一個客戶端 X 和一個服務器 Y ,然後 X 發送一個值給 Y,那麼唯一的一個服務器就有了這個值。
但我們試想一下現實世界中,服務器的數量不可能只有一個,所以假設有 n 個服務器 Y[n] ,如何將客戶端 X 發的值
讓多個服務器都能一致起來,這就是需要探究的一個問題。

而在論文中提到,一致性算法是從複製狀態機的背景下提出的。複製狀態機圖示如下:
在這裏插入圖片描述
複製狀態機是基於複製日誌來實現的,從上圖可知,每一個服務器都存儲一個包含一系列指令的日誌。
客戶端向一致性模塊發送指令,一致性模塊接收到指令然後增加到自己的日誌中,它和其他服務器上的一致性模塊進行通信來保證每一個服務器上的日誌最終都以相同的順序包含相同的請求。
一旦指令被正確的複製,每一個服務器的狀態機按照日誌順序處理它們,然後輸出結果被返回給客戶端。


2 Raft 一致性算法

針對上面提到的分佈式系統中一致性問題,Raft 便是一種可以實現一致性的協議(或者算法)。具體的講,它就是用來管理上圖複製狀態機中複製日誌的算法。

Raft通過選舉一個leader,並賦予給它完全的管理複製日誌權限來實現一致性。
leader從client接收日誌條目,然後將日誌條目複製到其他服務器中,並當可以保證安全性時告知其他的服務器需要應用日誌條目到它們的狀態機中。

這樣我們就將 Raft 算法分成三部分:

  • 領導選舉
  • 日誌複製
  • 安全性

具體內容下面分別來講述。


2.1 Raft 基礎知識

我們首先要了解一下Raft的一些基礎知識。
首先 Raft 中的服務器一共有 3 個狀態:

  • Follower
  • Candidate
  • Leader

三個狀態相互轉化關係圖如下:

在這裏插入圖片描述
也就是說,每個服務器起始的狀態都是 Follower,然後開始選舉之後,其中一個服務器稱爲 Candidate, 然後接受投票,若獲得大部分的投票則稱爲 Leader,當然從 Candidate 和 Leader 狀態都可以轉化成 Follower狀態。

而每一個時期,系統只能存在一個 Leader,如果大於1個,則錯誤,而其他的節點都是 Follower。Follower 都是被動的:他們不會發送任何請求,只是簡單的響應來自 Leader 或者 Candidate 的請求。


2.2 Leader Election

領導選舉是一種非常關鍵的步驟,也是實現Raft的第一個步驟。

過程如下:

首先系統中存在多個服務器,每個服務器都維護着自己的一個 election timeout,它是隨機設定的(一般是150~300ms)。
如果一個 Follower 在其 election timeout 時間裏都沒有收到任何消息,則它認爲系統中沒有可用的 Leader,那麼它會發起選舉已選出新的Leader。

如下圖所示,一共有 3 個服務器,每個服務器有一個 “進度條” 代表其 election timeout

一旦其中一個節點(下圖顯示的是節點A)的進度條走完,便成爲 Candidate。此時A開始一個新的 election term,併爲自己投票。

然後,節點A開始向其他節點發送 Request Vote(請求投票)RPC。

如果接收到A發送的RPC的其他節點還未投票過,則向 Candidate 投票, 並重置自己的 election timeout

一旦 Candidate 獲得了絕大多數 Follower 的投票,則它成爲 Leader。 【小弟們都服我做老大】

最後,Leader 便開始按另一個 timeout —— heartbeat timeout 指定的間隔向所有的 Followers 發送 Append Entries(附加日誌項)RPC。發送這個RPC是爲了 【告知其他服務器我是老大,從而建立自己的權威並且阻止新的老大的產生】

Followers 再響應每個 Append Entries RPC。 【對,你就是老大,我們都是小弟,跟着你幹】

這個選舉任期將持續到一個 Follower 停止接受心跳併成爲 Candidate。 【有小弟不接收老大的指揮,不幹了,要反抗,自己想成爲老大】

以上便是 Leader Election的細節。
總的來說,要開始一次選舉過程,Follower 先要增加自己的當前任期號並且轉換到 Candidate 狀態。然後它再並行地向集羣中的其他服務器節點發送 Request Vote RPCs 來爲自己拉票。Candidate 會繼續保持着當前狀態直到以下三件事情之一發生:

  • 情況一:它自己贏得了這次的選舉,成爲 Leader ;

    • 當一個候選人從整個集羣的大多數服務器節點獲得了針對同一個任期號的選票,那麼他就贏得了這次選舉併成爲領導人。每一個服務器最多會在一個任期號裏投出一張選票,按照先來先服務的原則,並確保只有一個Leader。
  • 情況二:其他的服務器成爲 Leader ;

  • 情況三:一段時間之後沒有任何一個獲勝的人。

    • 如果有多個跟隨者同時成爲候選人,那麼選票可能會被瓜分以至於沒有候選人可以贏得大多數人的支持。當這種情況發生的時候,每一個候選人都會超時,然後通過增加當前任期號來開始一輪新的選舉。然而,沒有其他機制的話,選票可能會被無限的重複瓜分。

在等待投票的時候,候選人可能會從其他的服務器接收到聲明它是領導人的附加日誌項 RPC。如果這個領導人的 Term(包含在此次的 RPC中)大於等於候選人的currentTerm,那麼候選人會承認領導人並回到跟隨者狀態。 相反,如果此次 RPC 中的 Term 比自己的currentTerm 還小,那麼候選人就會拒絕這次的 RPC 並且繼續保持候選人狀態。 【你強我就服你,你繼續上,我繼續成爲小弟。但如果我強,我就不服,我就要反抗】

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