在建構大規模分散式系統(如 Kubernetes 的 etcd、Kafka 的 KRaft、CockroachDB 或 TiDB)時,跨網路的多個獨立節點如何對某個資料值或操作日誌達成全域唯一且不可撤銷的共識(Consensus)?
然而,在真實的實體世界中,網路分區(Network Partition)、光纖被挖斷、伺服器硬體當機與時鐘漂移是必然發生的客觀現實。
從理論層面的 CAP 定理、PACELC 模型,到工程落地的 Paxos 與 Raft 演算法,分散式共識是整個現代雲端原生與分散式儲存架構的最底層基石。
本文將從理論嚴格證明出發,深度拆解 CAP/PACELC 的權衡本質,並全景剖析 Raft 演算法的狀態機與複製日誌架構。
1. CAP 定理的嚴格定義與工程誤區
Eric Brewer 提出的 CAP 定理是分散式領域中最被廣泛引用、但也最常被過度簡化與誤讀的理論。
網路分區 P 是客觀物理現實
實體網路的光纖損壞、交換機故障必然發生;因此架構師的真實決策不是「三選二」,而是在分區發生時選擇保證強一致(CP)或維持高可用(AP)。
分區發生時:A 與 C 的取捨
PC 模式:拒絕非多數派節點讀寫,防止髒讀(如 etcd、ZooKeeper)。
PA 模式:允許分區孤島繼續回覆,容忍暫時不一致(如 Cassandra)。
平穩無分區時:Latency (L) vs. Consistency (C)
EL 模式:非同步複製,追求個位數毫秒極致低延遲。
EC 模式:強制多副本 Raft/Paxos 同步落盤,以延遲換取 100% 強一致性。
1.1 三大特性的嚴格學術定義
- 一致性(Consistency):在 CAP 定理的原始數學證明中,特指線性一致性(Linearizability / Atomic Consistency)。即所有節點上的所有讀寫操作必須表現得像是在單一全域時鐘下依序原子執行,讀操作必須永遠返回最新寫入的值。
- 可用性(Availability):特指每一個非故障節點(Non-failing node)收到的所有非錯誤請求,都必須返回非錯誤回應(No Error / Timeout)(即使該回應回傳的是舊資料)。
- 分區容忍性(Partition Tolerance):在分散式網路中,允許節點之間因網路中斷而丟失任意數量的訊息。
2. 超越 CAP:PACELC 延遲權衡模型
| 系統分類 | 分區時 (P) 選擇 | 正常時 (E) 選擇 | 代表系統 |
|---|---|---|---|
| PC/EC | Consistency (強一致) | Consistency (強一致) | Spanner, etcd, ZooKeeper, TiDB |
| PA/EL | Availability (可用) | Latency (極致低延遲) | DynamoDB (最終一致), Cassandra |
| PA/EC | Availability (可用) | Consistency (強一致) | MongoDB (預設讀主寫主模式) |
3. Raft 共識協定核心架構
經典的 Paxos 演算法因晦澀難懂且難以在工業界直接實現而著稱。史丹佛大學團隊提出了 Raft 演算法,其核心思想是將共識問題分解為兩個完全獨立的子問題:領導者選舉(Leader Election) 與 日誌複製(Log Replication)。
3.1 三種角色狀態轉換
FOLLOWER (跟隨者)
完全被動響應來自 Leader 的日誌追加與心跳。當隨機化逾時(150ms~300ms)到達未收到心跳時,自增 Term 躍遷為 Candidate。
CANDIDATE (候選人)
自增 Term 並向全體節點廣播 RequestVote RPC 拉票。若贏得多數票(Quorum)則晉升 Leader;若收到更高 Term 則退回 Follower。
LEADER (領導者)
唯一全權負責受理 Client 寫入、為日誌指派 Index,並向所有 Follower 同步 AppendEntries RPC;持續廣播心跳維繫權威。
- Follower(跟隨者):完全被動,僅接收來自 Leader 的日誌追加與心跳,若心跳逾時則發起選舉。
- Candidate(候選人):主動拉票,向其他節點發送
RequestVoteRPC。 - Leader(領導者):唯一負責處理所有客戶端請求、日誌序列化、並向所有 Follower 同步
AppendEntriesRPC。
4. Raft 兩大核心流程機制
4.1 領導者選舉與隨機化逾時(Randomized Election Timeouts)
為了防止多個 Follower 在同一瞬間同時逾時發起選舉導致選票被均分(Split Vote),Raft 引入了隨機化選舉逾時機制(例如 150ms ~ 300ms 隨機抖動)。
- 第一個逾時的節點將率先自增任期號(Term),並向其他節點廣播拉票。
- 每個節點在同一 Term 內遵循「先到先得」原則投出一票。
- 獲得過半數(Quorum:
floor(N / 2) + 1) 投票的 Candidate 立即勝出成為新任 Leader。
4.2 日誌複製與兩階段提交安全保證
客戶端發起寫入與 Leader 日誌預寫
Client 發送 Set x=5 請求。Leader 將操作附加至本地 WAL 日誌中,標記為未提交(Uncommitted)狀態。
平行複製至所有 Follower 節點
Follower 接收到日誌項目並確認前置 Index 與 Term 無誤後,寫入本地磁碟並向 Leader 回覆 ACK 成功。
推進 Commit Index 並回覆客戶端
一旦過半節點持久化成功,Leader 立即推進 commitIndex,將日誌應用至狀態機並回覆客戶端成功;日誌此時具有不可撤銷的安全性保證。
Leader 接收 Client 寫入請求後,先以未提交狀態寫入本機日誌,再透過 AppendEntries RPC 平行廣播複製至各 Follower。當過半數 Quorum 節點均回報持久化成功後,Leader 立即推進 commitIndex,並向 Client 回覆確認。
4.3 領導者完備性(Leader Completeness Safety Invariant)
Raft 在投票階段施加了強硬的安全限制:
- 投票限制:若 Candidate 的日誌沒有投票節點的新(即 Candidate 的最後一條日誌的 Term 較小,或 Term 相同但 Index 較小),投票節點一律拒絕投票!
- 保證結果:任何成功當選的 Leader,必然已經包含了所有在歷史任期中已被提交(Committed)的全部日誌,從根本上杜絕了日誌被覆蓋或倒退的致命缺陷!
5. 總結
- 在高可用金融資料庫與元數據協同層(etcd / ZooKeeper / Raft),我們堅定選擇 CP / PC/EC 架構,確保分散式狀態的零丟失與線性一致。
- 在跨洲超大海量社群與時序監控系統,我們透過 AP / PA/EL 換取極致的寫入延遲與分區容錯性。
- 理解共識協議的代價與極限,是每一位分散式架構師的必修課。
