共识:Paxos 与 Raft
**共识(consensus)**让一组节点就一个值达成一致,是状态机复制(每台机器执行同样的命令序列)的底座。本章讲共识解决什么问题、Paxos 的两阶段、Raft 的分解与设计取舍(→ 并发与同步)。
共识解决什么问题
Section titled “共识解决什么问题”状态机复制:把一个确定的状态机复制到 台机器,每台执行同样的命令序列——状态就一致。共识的任务:让所有机器对命令序列的顺序达成一致。
正式定义的三个性质:
- 一致性(agreement):没有两个节点选择不同的值;
- 有效性(validity):选出的值必须来自某个节点提议;
- 终止性(termination):最终会选出值(活性——受 FLP 约束,靠超时,→ 故障模型与 CAP)。
为何需要多数派(quorum): 个节点容忍 个故障——多数派交集保证安全性:任何两个多数派至少共享一个节点,它携带旧决议,防止"两个值都被选"。写入要等多数派确认,读多数派信息(或租约)——共识的一切代价都来自多数派。
Paxos:两阶段
Section titled “Paxos:两阶段”Paxos 解决"单个值"的共识,两个角色(提议者/接受者)两个阶段:
- Prepare(准备):提议者选编号 问多数派"能承诺不接受比 旧的提议吗";
- Accept(接受):多数派承诺后,提议者发"接受值 v"( 或已承诺的最高编号提议的值)。
不变式:一旦某个值被多数派接受,之后任何提议都会选它——安全性由此成立。活性靠领导者(避免提议冲突):Multi-Paxos 优化为"稳定的领导者跳过 prepare 阶段",每个值一轮 accept——这就是工程中实际跑的形态。
Paxos 以难以理解著称:正确性证明绕(不变式隐藏在两阶段的承诺里)、角色与优化多、论文本身晦涩——Lamport 自己都写了 "Paxos Made Simple" 还是不够。
Raft:为可理解性而生
Section titled “Raft:为可理解性而生”Raft(2014)显式以可理解性为目标:把共识分解为选举、复制、安全三个子问题,每个独立可理解。
- 任期(term)编号单调递增;节点状态:领导者/跟随者/候选人;
- 跟随者超时未见心跳 → 变候选人、请求投票;多数派投票者成为领导者;
- 一个任期至多一个领导者(每节点每任期只投一票)——任期是逻辑时钟(→ 时间、时钟与事件顺序)。
领导者接收命令 → 追加到本地日志 → 并行发给跟随者 → 多数派确认即提交 → 应用到状态机、通知跟随者。日志按序复制——状态机复制的命令序列。
- 选举限制:投票者不投给"日志不如自己新"的候选人——保证新领导者拥有全部已提交日志;
- 提交规则:只提交"当前任期"的日志(间接提交旧任期的)——防止已复制的旧任期条目被覆盖。
Raft 的取舍:更强的领导者(一切经领导者,跟随者被动)换可理解性;Paxos 更对称但绕。Raft 的正确性可读、可证、可实现——工程主流(etcd、TiKV、CockroachDB、Consul)都选了 Raft。
共识的代价是至少一轮跨节点往返:
- 每次写要多数派确认——延迟受最慢的多数派成员约束;
- 节点数增加:容错更强、延迟略增(3 或 5 个是常见选择);
- 共识不便宜,能不用就不用——单一协调者 + 持久化(够用时)比集群共识快;共识用在必须容错强一致的地方:元数据、锁、配置(→ 协调服务与实践模式)。
- 共识 = 状态机复制的底座:一致性、有效性、终止性
- 多数派交集保证安全性: 容忍 ,一切代价来自多数派
- Paxos 两阶段(Prepare/Accept);Multi-Paxos 用稳定领导者优化
- Raft 把共识分解为选举、复制、安全三个子问题;选举限制保证新领导者有全部已提交日志
- 共识的代价是至少一轮跨节点往返:用在必须容错强一致的地方