共識演算法 Raft

★★★★★Reviewed

FromDDIADatabase Internals

📚 From the Books

共識演算法 RaftConsensus

讓一群節點對「一連串操作的順序」達成一致,即使有節點崩潰、網路延遲。Raft 把共識拆成 leader election + log replication + safety 三塊,刻意設計成比 Paxos 好理解——而能達成共識,等價於能做全序廣播。

🧠 Intuition

TIP

Raft = 「選一個老大,大家只抄老大的流水帳」。任何時刻最多一個 leader,所有寫入都先進 leader 的 log,再複製給多數派;commit 的判準很簡單:這條 log 被多數節點存下來了

⚖️ Tradeoffs

Leader Election — term 與投票
  • follower 在 election timeout 內沒收到 leader 心跳,就自增 term、轉成 candidate、向所有人拉票。
  • 每個節點一個 term 只投一票,candidate 拿到多數票才當選——多數派保證一個 term 不會選出兩個 leader。
  • election timeout 隨機化,避免大家同時開選一直瓜分選票 (split vote)。
  • term 是邏輯時鐘:任何訊息帶著比自己小的 term 直接丟棄;看到更大的 term 就立刻退回 follower。
Log Replication — append 與 commit index
  • 客戶端寫入只進 leader:leader 把 entry append 到自己的 log,再透過 AppendEntries 複製給 followers。
  • 一條 entry 被多數派持久化後,leader 將它標記為 committed、推進 commit index,才回覆客戶端並套用到狀態機。
  • AppendEntries 帶上前一條的 index/term 做一致性檢查,不符就回退、逼 follower 與 leader 對齊——log 只會被 leader 覆寫趨同。
  • commit index 隨心跳傳給 followers,讓它們知道可以安全 apply 到哪裡。
Safety — Log Matching 與選舉限制
  • Log Matching:若兩個 log 在某 index 有相同 (index, term),則該點之前完全相同——由 AppendEntries 的一致性檢查維持。
  • 選舉限制:節點只把票投給 log 至少和自己一樣新的 candidate(比 last term,再比 last index)。這保證當選者一定握有所有已 committed 的 entry。
  • 兩者合起來給出 Leader Completeness:committed 的東西絕不丟失、絕不被覆寫——這是共識「一旦決定就不反悔」的根。
  • 微妙處:leader 不能僅憑「多數派已存」就 commit 前任 term 的 entry,要靠 commit 自己 term 的新 entry 來間接帶過(Figure 8 問題)。
與 Paxos 對比 — 可理解性是設計目標
  • (Multi-)Paxos 正確但難懂、難正確實作;Raft 用「強 leader + 隨機選舉 + 連續 log」換取可理解性與工程落地
  • Raft 限制更強:log 不允許有洞、只能由 leader 流向 follower;Paxos 較自由但也更難推理。
  • 實務影響:etcd / Consul / TiKV / CockroachDB 等都選 Raft——好懂、好測、好除錯往往比理論優雅更重要。

🔑 Takeaways

✍️ My Notes

2026-07-01

  • Q: 為什麼說「共識等價於全序廣播 (total order broadcast)」?Raft 不就是在選 leader 嗎?
  • A: 兩者可互相化約。有了共識,就能對「下一條訊息是誰」反覆達成一致,串起來就是所有節點看到相同順序的相同訊息——這正是全序廣播;反過來,有了全序廣播,要對單一值達成共識,只要大家都取廣播序的第一條即可。Raft 的 replicated log 就是全序廣播的具體實作:每條 log entry 是一則被全序投遞的訊息。也因此共識能拿來做線性一致儲存、fencing token(用單調遞增的 log index / term)這類需要全序的東西。

📖 Further Reading

🔗 Dive Deeper