raft協議

蒙恬括發表於2022-04-17

Raft協議是比paxos協議更容易理解和實現的一種一致性協議。http://thesecretlivesofdata.com/raft/   這個網址動態演示了Raft協議的整個過程。跟著記錄一下:

1:Raft是一個可被理解接受的分散式一致性協議。

 2:什麼是分散式一致性協議呢?以一個例子為例

 

 3:假設有一個單節點系統

 

 

4:假設這個節點是個資料庫伺服器,只儲存了一個資料。

 

 5:假設儲存的資料是 X

 

 

6: 現在有個客戶端可以向這個server傳送資料

7:向server端傳送了修改資料的請求

 8:在一個節點上,很容易做到資料一致性。

 9:如果有多個節點,又如何讓資料保持一致性呢。這就是分散式一致性的問題。

 

 

 10:Raft是一種用於實現分散式一致性的協議。

 

 

 

11:讓我們從總體上看一下它是如何工作的。一個節點的狀態分為三種:Follower,Candidate,Leader

 

 

 

 12:所有的節點剛開始都是follower的狀態。

 

 13:如果follower狀態的節點,沒有接收到來自leader的資訊,那麼這個節點就可以變成candidate狀態

 

 14:候選者節點會向其他節點傳送投票請求。

15:候選者如果得到了大多數節點的投票,這個候選者就變成了leader。

 

 上述過程被稱為Leader選舉過程。

 

 

 

當leader選舉出來之後,對於當前系統的所有變更都通過leader來完成。

16:每次的變更,都會在節點上的日誌中新增一條記錄。

 

 17:這條日誌記錄當前還是未提交的狀態,所以還沒有真正的更新節點上的值。

 

 18:leader節點為了提交這條記錄,首先把它複製到其它follower節點上去。

 

19:leader節點等待大多數follower節點將這條變更記錄寫入成功並返回。

 

20:到這裡,這條變更記錄在leader節點才處於提交狀態,節點的狀態記錄為 “5”

21:leader節點通知其他follower節點變更記錄進行提交。

 

22:當前叢集現在對於系統狀態而言已經達到了一致性。

 

 上述過程稱為日誌複製

我們下面詳細看下leader的選舉過程

23:在Raft協議中有兩個超時時間的設定來控制選舉。

 

24:第一個是選舉超時時間。

 

 

 25:這個選舉超時時間是指follower等待變成candidate的時間。

 

 

 26:這個選舉超時時間是150ms~300ms之間的隨機值。

 

 

 

27:每個節點在election time 內自我選舉成candidate,然後開始新一輪的選舉投票。候選者會傳送投票請求給其他節點,讓其他節點投票給自己稱為leader。

 

 

 

 

 

28:如果接收到請求的節點在當前週期內還沒有進行過投票,那麼它就會投票給當前這個candidate。然後receiving節點會重置選舉超時時間。一旦candidate接收到大多數節點的投票,它就會變成leader。

 

 

 29:leader 開始向其他follower傳送 追加變更記錄的資訊.

 

 

 30:  這些訊息按心跳超時時間作為時間間隔傳送到其他節點。

 

 31:follower們也會給每一個訊息進行響應。

 

 

 32:直到一個follower停止接收leader傳送過來的心跳並變成candidate之後這個選舉過程才算結束。注意!follower和leader通訊過程中,自我選舉也一直都在,只是每次收到leader的心跳之後就被重置了。

         這也是後面leader掛了之後,馬上開始election的原因。

 

 33:接下來看下把lader停掉,叢集是怎麼重新選舉的。

34:假設B 原來是leader,突然掛了,也就沒法向其他follower節點傳送心跳了,正如32步驟中說的那樣,另外兩個節點一直在進行election term,下圖是A節點首先成為了candidate,然後傳送投票請求給C,C響應成功,

       A節點就變成了leader。

 

35:下面我們看下投票發生分裂的情況,當叢集中投票有多個follower節點同時變成candidate。下面第二個圖,A,C節點同時變成candidate,並向其他節點傳送vote請求。

 

36:這兩個進行election 的節點都收到了兩個節點的投票。

 

 

 

 37:兩個候選者得到的票數一樣,開始下一個週期的投票。

 

等下個週期開始A,C看那個節點先發起投票。最後A得到了大多數票數。

 

 

下面詳細說明下  Log Replication的過程

   38:一旦選定了一個leader之後,我們需要複製所有的變更記錄到系統的所有節點。

 

 39:複製的這個過程靠leader和follower之間心跳來維持的。

 

 40:過程如下:

1:一個客戶端過來向leadeer傳送一條資訊,新增了5這條資料,在leader這邊先寫入本地日誌set 5。

2: 下次心跳的時候,leader帶著這條set 5日誌操作向其他follower傳送請求。

3:當叢集中大多數follower節點ack的時候,leader節點才將這條記錄進行commit比如寫入磁碟落地等。

4:響應客戶端。

41:在上面的基礎上增加2的過程如下。

 

Raft協議還可以保證在發生分割槽的情況下保持系統一致性。

 

 42:假設五個節點發生了分割槽,其中A,B是一個區的,C,D,E是一個區的

 

 43:分割槽一單發生C,D,E叢集就會開始election term ,假設C節點變成了第二個leader。

 

 

 

 

44: 假設有個客戶端來請求B節點進行set 3,但是由於分割槽的原因B節點不能複製這條變更記錄到大多數的節點,所以這條記錄一直處於uncommit的狀態,也不能給客戶端進行響應。

 

 45:假設另外一個分割槽有一個客戶端來進行連線在C節點操作set 8操作,由於C可以複製到大多數節點,所以這個set 8的操作是會成功的。

 

 46:當分割槽的問題解決之後,B節點會發現比它更高階的election term 也就是C,B就會主動放棄leader成功follower。並且,A,B節點上處於uncommit的記錄也會回滾掉,接收新leader發來的log。

 

 

 

 

這樣這個叢集之間的節點也就處於一致了。

 

相關文章