写在前面
本文讲共识算法(Consensus)——多个节点如何对某个值达成一致。它是 CP 系统(etcd、Zookeeper、TiKV)实现强一致性的核心。重点讲 Raft(比 Paxos 好懂),它是现代分布式系统的共识算法标配。
一、什么是共识问题
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
| 共识(Consensus):多个节点就某个决议(值)达成一致
典型场景:
- 选主:哪个节点当 Leader
- 日志复制:操作的顺序(先 A 后 B,还是先 B 后 A)
- 状态机复制:所有副本状态一致
难点:
节点可能宕机
网络可能丢包/延迟/分区
没有全局时钟
但必须保证:
所有正常节点达成相同决议
决议一旦达成不可更改
能容忍少数节点故障
|
二、Paxos(经典但难懂)
1
2
3
4
5
6
7
8
9
10
| Paxos(Lamport 1998)是共识算法的鼻祖
数学上严谨、正确
但极难理解、更难实现
核心思想:多数派(Quorum)+ 两阶段(Prepare/Accept)
只要多数节点同意,决议通过
实际系统很少直接用 Paxos(太复杂)
多用 Raft(更易懂的等价算法)或 Paxos 变体
(Doris 用 Paxos 变体、Chubby 用 Paxos、Spanner 用 Paxos)
|
三、Raft 核心思路
Raft(2013)的设计目标就是"好懂"。它把共识拆成三个子问题:
1
2
3
4
5
6
7
8
9
10
11
| 1. Leader 选举(Leader Election)
选出一个 Leader 处理所有请求
2. 日志复制(Log Replication)
Leader 接收请求,复制到其他节点,多数确认后提交
3. 安全性(Safety)
保证已提交的日志不被覆盖
核心简化:把"任意节点都可提议"简化为"只有 Leader 提议"
一切由 Leader 主导,逻辑清晰
|
3.1 节点状态
1
2
3
4
5
6
7
8
9
10
| 每个节点三种状态:
Follower — 跟随者,被动接收 Leader 指令
Candidate — 候选者,发起选举
Leader — 领导者,处理所有请求
状态转换:
Follower ──(超时无心跳)──→ Candidate
Candidate ──(获多数票)──→ Leader
Candidate ──(发现更高term的Leader)──→ Follower
Leader ──(发现更高term)──→ Follower
|
四、Leader 选举
1
2
3
4
5
6
7
8
9
10
11
12
13
| 1. 初始都是 Follower
2. 一段时间没收到 Leader 心跳 → 超时
3. Follower 变 Candidate,term+1,给自己投票,发 RequestVote
4. 其他节点收到:
- 如果 Candidate 日志不比自己旧 → 投票
- 每个 term 只投一票(先到先得)
5. Candidate 收到多数票 → 成为 Leader
6. Leader 定期发心跳,维持权威
term(任期)是 Raft 的逻辑时钟:
单调递增
每个 term 最多一个 Leader
term 小的服从 term 大的
|
1
2
3
| 避免选主冲突(脑裂):
随机化选举超时时间(150~300ms 随机)
避免多个节点同时超时、同时竞选
|
五、日志复制
1
2
3
4
5
6
7
8
9
10
11
12
13
14
| Leader 处理客户端请求的流程:
1. 客户端发请求给 Leader(写命令)
2. Leader 写入本地日志(未提交)
3. Leader 并发发给所有 Follower(AppendEntries)
4. Follower 写入本地日志,回复 ACK
5. Leader 收到「多数」ACK → 提交(commit)
6. Leader 回复客户端「成功」
7. Leader 在下次心跳通知 Follower 提交
8. Follower 提交,状态机应用
关键:多数(Quorum)确认才提交
3 节点集群,2 个确认即可(容忍 1 个故障)
5 节点集群,3 个确认即可(容忍 2 个故障)
|
1
2
3
4
5
6
7
8
9
| Quorum 公式:
N 个节点,多数 = ⌊N/2⌋ + 1
可容忍故障 = N - 多数
3 节点:多数 2,容错 1
5 节点:多数 3,容错 2
7 节点:多数 4,容错 3
常用奇数节点(3/5/7),性价比高
|
六、安全性保证
Raft 保证几个关键不变式:
1
2
3
4
5
6
7
8
9
10
11
12
| 1. Leader 完整性
如果一条日志在某个 term 提交了,
那它一定存在于所有后续 term 的 Leader 日志中
2. 状态机安全
所有节点按相同顺序应用相同日志 → 状态一致
3. 选举限制
投票时,Follower 只投给「日志至少和自己一样新」的 Candidate
→ 保证新 Leader 不会丢已提交日志
这些不变式保证了:已提交的数据绝不丢、所有副本最终一致
|
七、脑裂与 Quorum
1
2
3
4
5
6
7
8
9
10
| 脑裂(Split Brain):网络分区导致两个 Leader
例:5 节点分区成 3 + 2
3 那边有多数,能选主、能提交(正常工作)
2 那边没多数,选不出主 / 无法提交(拒绝服务)
→ Quorum(多数派)天然防止脑裂
只有拥有多数的分区才能写入,少数分区自动失效
这就是 CP 系统"分区时牺牲可用性"的体现
|
八、实际应用
1
2
3
4
5
6
7
8
9
10
| 系统 共识算法 用途
──────────────────────────────────────────────
etcd Raft K8s 配置/服务发现
Consul Raft 服务发现/配置
TiKV Raft 分布式 KV(TiDB 底层)
CockroachDB Raft 分布式 SQL
Nacos Raft(自研) 配置/注册中心
Doris Paxos 变体 MPP 数据库
Zookeeper ZAB(Paxos 类) 协调服务
Spanner Paxos Google 全球数据库
|
1
2
3
4
5
6
7
| Raft 为什么流行:
✓ 好懂(相比 Paxos)
✓ 易实现
✓ 工程友好(Leader 模型清晰)
✓ 强一致性 + 容错
现代新系统几乎都选 Raft
|
九、共识 vs 一致性 vs 复制
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
| 容易混的三个概念:
复制(Replication)
数据在多节点存副本(手段)
主从复制、多主复制、无主复制
共识(Consensus)
多节点就值/顺序达成一致(强一致复制的核心机制)
Raft、Paxos
一致性(Consistency)
客户端看到的数据一致性级别(结果)
强一致、最终一致
关系:共识算法(Raft)实现强一致的复制(手段),从而提供强一致性(结果)
|
十、小结
- 共识:多节点对决议达成一致,容忍少数故障
- Paxos:鼻祖但难懂;Raft:好懂的等价算法,现代标配
- Raft 三子问题:Leader 选举、日志复制、安全性
- 核心机制:Leader 主导 + Quorum(多数确认才提交)+ term(逻辑时钟)
- 容错:N 节点容忍 ⌊(N-1)/2⌋ 故障,常用 3/5/7 节点
- 脑裂:Quorum 天然防止,少数分区无法写入
- 应用:etcd/Consul/TiKV/CockroachDB 等
下一篇讲分布式锁——如何用共识系统/Redis 实现互斥。