談到分布式架構就不得不談到相關的分布式一緻性協定,比如:Pasox、Raft等分布式一緻性協定,本篇就來談談目前主流的Raft協定@mikechen
Raft協定簡介
Raft是分布式的一緻性協定,其相對Pasox更加簡單,都是為了實作 一緻性 産生的,解決分布式系統的資料一緻性和高可用。
Raft協定将一緻性協定的核心内容分拆成為幾個關鍵階段:包括:上司選舉(leader selection)、日志複制(log replication)等以簡化流程,提高協定的可了解性。
是以搞懂Raft協定重點就是要了解Raft協定角色,以及上司選舉、日志複制這3大核心點,下面我分别詳解@mikechen
Raft協定角色
在Raft算法中一個叢集裡面的所有節點有以下三種狀态:
Raft協定的每個副本都會處于三種狀态之一:Leader、Follower、Candidate。
1.跟随者(follower)
類似選民,完全被動的角色,這樣的伺服器等待被通知投票。
2.候選者(candidate)
候選者就是在選舉過程中提名自己的實體,一旦選舉成功,則成為上司者。
3.上司者(leader)
上司者的作用:處理用戶端互動,日志複制等動作,Raft 要求系統在任何一個時刻最多隻有一個 Leader,正常工作期間隻有 Leader 和 Follower。
Raft 協定角色狀态轉換,如下圖所示:
上司leader選舉
Raft通過心跳機制來觸發leader選舉,當一個伺服器啟動時,預設位于followers狀态,并且一直持續知道它一直接受到leader的RPC請求。
leader會周期性發送心跳給所有的followers,如果follower一段時間内沒有接受到心跳,那麼就認為目前沒有leader應該開始leader selection。
一個最小的 Raft叢集需要三個參與者,這樣才可能投出多數票,如下圖所示:
初始狀态下 ABC三個節點開始選舉Leader,Leader選舉過程中有三種可能的情形發生。
第一種:A節點要投自己一票,并把提議拉票請求發給B和C,如下圖所示:
B和C接受了A的提議,也投票給A,最終A成為Leader。
第二種:A節點投了自己一票,B節點也投了自己一票,C節點支援A節點的提議,如下圖所示:
第二種少數服從多數,最終A成為Leader。
第三種:A節點、B節點、C節點都各自投了自己一票,如下圖所示:
這樣就沒有節點獲得多數票,第三種情況本輪投票無效,出現了平票(Split Votes),因為沒有任何一方獲得多數票,是以要發起新的一輪投票。
Raft協定為了不讓選舉機制反複出現平票,定義了一個随機逾時機制(randomized election timeouts),一旦發生平票,平票的節點會各自再來一次随機timeout倒數,然後重新拉票,先發起拉票的節點就可以優先獲得了多數節點的投票。
日志複制
在 Raft 算法中需要實作分布式一緻性的資料被稱作日志, Raft 算法中的資料送出記錄,會按照時間順序進行追加,Raft 也是嚴格按照時間順序并已一定的格式寫入日志檔案中。
下面這張圖就描述了Raft叢集中日志的組成結構:
每一個小方框就是entry,每個日志項包含一條指令、任期資訊、日志項在日志中的位置資訊(索引值 LogIndex)。
- 指令:由用戶端請求發送的執行指令,有點繞口,我覺得了解成用戶端需要存儲的日志資料即可。
- 索引值:日志項在日志中的位置,需要注意索引值是一個連續并且單調遞增的整數。
- 任期編号:建立這條日志項的上司者的任期編号。
Raft 的日志複制過程,大緻如下圖所示:
1.上司者接收到用戶端發來的請求,建立一個新的日志項,并将其追加到本地日志中;
2.接着上司者通過追加條目 RPC 請求,将新的日志項複制到跟随者的本地日志中;
3.當上司者收到大多數跟随者的成功響應之後,則将這條日志項應用到狀态機中,可以了解成該條日志寫成功了;
4.最後上司者傳回日志寫成功的消息響應用戶端。
以上
更多分布式架構系列、阿裡架構師進階系列,請檢視以下文章:
阿裡架構師進階從0到1全部合集(建議收藏)