Raft 簡介

共識是分佈式容錯系統的基礎問題,是指多個服務器對值達成一致。

raft 設計目的:

  1. 易於理解
  2. 跟 Paxos 有同等容錯能力和性能

raft 服務器狀態:

  1. 領導(leader):處理所有客戶端請求
  2. 跟隨者(follower):被動響應候選人和領導
  3. 候選人(candidate):中間狀態,在選舉時出現

領導選舉(Leader election)

terms(任期)

  1. 所有的服務器管理着當前任期:
    • 任期單調遞增
    • 作爲邏輯時鐘管理
    • 無論服務器在何時進行通信,任期會進行交換
  2. 任期交換規則:
    • 當 A 的任期大於 B 的任期時,B 更新任期爲 A 的
    • 當 A 的任期大但 B 認爲自己纔是領導時,B 迴歸跟隨者狀態
    • 當 A 的任期大但收到來自 B 的請求時,A 拒絕 B 的請求,B 更新任期後再發出請求

跟隨者狀態

  1. 所有服務器都是從跟隨者狀態開始
  2. 所有服務器都有本地的計時器
  3. 只要在計時內能收到來自領導或候選人的消息(心跳消息),就一直保持跟隨者狀態
  4. 當計時內未收到心跳消息,則認爲系統沒有存活的(viable)領導,開始選舉流程,自提名(nominate)爲候選人

如何解決多個跟隨者自提名爲候選人的問題?各個服務器使用隨機的計時超時

候選人狀態

  1. 跟隨者進入後續人狀態過程:增加當前任期,並設置狀態爲候選人
  2. 給自己投一票,然後再發送投票請求到其他服務器
  3. 其他服務器收到投票請求後,會增加任期,然後投票
  4. 候選人計票,當得到大多數選票後,轉爲領導狀態,併發送心跳消息;若落選,退出到跟隨者狀態。

日誌複製(Log replication)

日誌:

  1. 每個節點都維護着一份操作日誌(action log)
  2. 日誌中的每一條目(entry)包括:操作和任期(action and term),任期表示節點接收到操作的時間。

複製過程:

  1. 當客戶端請求進入領導節點時(rd<-Ready),領導節點先追加條目到自身的日誌中(storage append rd.Entrieds)
  2. 接下來,領導節點告知其他節點追加條目,並等待確認追加( transport send rd.Messages)
  3. 正如選舉過程,複製過程也是遵循少數服從多數的原則,當收到大多數節點的確認時,領導會提交條目(commit entry),然後更新狀態機,再回覆成功消息給客戶端和其他節點。(applyConfChange & advance)

如果跟隨者失敗了,領導會不斷嘗試去追加,一旦跟隨者復活,條目會被最終提交。

如果領導失敗了,那麼條目將不會被提交,進入下個任期選舉,併產生新的條目。

etcd-raft

go.etcd.io/etcd/raft/v3

etcd/raft 中的心跳和選舉週期都是通過邏輯時鐘控制的,一般設置心跳週期爲1 個邏輯時鐘,選舉週期爲 10 個邏輯時鐘。接入 etcd/raft 時,需要自定義一個 Ticker,然後在 tick 之後,以心跳爲例,內部會將 heartbeatElapsed 自增,然後判斷是否到達設定的 Timeout,到達則恢復 heartbeatElapsed 爲 0,並執行心跳操作。

參考

FSM ppt

https://raft.github.io/

https://db.cs.duke.edu/courses/compsci512/spring15/lectures/raft-guest.pptx

http://thesecretlivesofdata.com/raft/

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