Paxos 算法
Paxos 是 Leslie Lamport 于 1998 年提出的分布式共识算法,是第一个解决共识问题的算法。Paxos 理论完备但实现复杂,被公认为难以理解。
Paxos 的背景
在 Paxos 之前,分布式共识问题没有通用的解决方案。大多数系统依赖单一领导者或超时机制,无法处理网络分区和节点故障。
Paxos 的名字来源于希腊岛屿 Paxos,岛上立法机构通过投票制定法律。Lamport 用这个类比来描述共识过程。
Paxos 的角色
Proposer(提议者)
Proposer 提出提案,提案包含编号和值。Proposer 的目标是让 Acceptor 接受它的提案。Proposer 可以有多个,但通常只有一个 Proposer 能够成功(称为 Leader)。
Acceptor(接受者)
Acceptor 接受或拒绝提案。Acceptor 可以有多个,但只有多数派接受才能达成一致。Acceptor 必须持久化存储已接受的提案,否则重启后会丢失状态。
Learner(学习者)
Learner 获取已接受的提案,学习达成一致的值。Learner 可以从 Acceptor 获取已接受的提案,也可以从其他 Learner 获取。
Basic Paxos
Basic Paxos 是 Paxos 的基础算法,用于达成一次共识。Basic Paxos 包含两个阶段:Prepare 阶段和 Accept 阶段。
Prepare 阶段
Proposer 选择一个提案编号 n,向多数派 Acceptor 发送 Prepare(n) 请求。
Acceptor 收到 Prepare(n) 请求后,如果 n 大于它之前响应过的所有 Prepare 请求编号,则承诺不再接受编号小于 n 的提案,并返回它之前接受过的最大编号的提案(如果有)。
如果 n 小于或等于它之前响应过的 Prepare 请求编号,则拒绝 Prepare 请求。
Accept 阶段
如果 Proposer 收到多数派 Acceptor 的 Prepare 响应,则发送 Accept(n, value) 请求。如果响应中有已接受的提案,则选择响应中编号最大的提案的值;否则,Proposer 可以自由选择值。
Acceptor 收到 Accept(n, value) 请求后,如果 n 大于或等于它承诺过的最大编号,则接受该提案;否则拒绝。
Learn 阶段
一旦 Proposer 收到多数派 Acceptor 的 Accept 响应,就认为提案已达成一致,可以通知 Learner。Learner 可以从 Proposer 或 Acceptor 获取已接受的提案。
Paxos 的安全性
安全性保证
Paxos 保证安全性:如果一个提案被多数派接受,那么该提案的值将被所有后续提案保持不变。这意味着一旦某个值被选定,后续提案只能选择这个值。
Paxos 还保证活性:如果没有提案被接受,Proposer 可以不断增加提案编号,最终会有提案被接受。
活性受阻
Paxos 的活性可能受阻:如果两个 Proposer 交替提出 Prepare 请求,但都未能完成 Accept 阶段,那么系统无法达成一致。这种情况被称为活锁。
活锁的解决方案:选举 Leader,只允许 Leader 提出提案。Leader 可以是稳定的(长时间不变),也可以是动态的(故障时重新选举)。
Multi-Paxos
Basic Paxos 只能达成一次共识,效率低(每次共识需要两轮 RPC)。Multi-Paxos 是 Basic Paxos 的优化,通过选举 Leader 减少 RPC 次数。
Leader 选举
Multi-Paxos 选举一个稳定的 Leader,由 Leader 提出所有提案。Leader 可以通过 Basic Paxos 选举,也可以通过外部服务(如 ZooKeeper)选举。
Leader 的优势:Proposer 只有一个,可以跳过 Prepare 阶段,直接进入 Accept 阶段。这减少了 RPC 次数,提高了吞吐量。
Leader 的劣势:Leader 可能成为瓶颈。如果 Leader 故障,需要重新选举,影响可用性。
日志复制
Multi-Paxos 将多个提案组织成日志,每个提案对应日志中的一个条目。Leader 接收客户端请求,将请求追加到日志,然后复制到 Follower。
日志复制的流程:Leader 发送 Accept(n, log_entry) 请求给 Follower,Follower 接受后追加到本地日志。多数派接受后,Leader 认为日志条目已提交。
日志的安全性:已提交的日志条目不能修改。日志条目按顺序提交,Leader 不能跳过某个条目提交后面的条目。
Paxos 的实现
Paxos 的实现复杂,容易出现错误。Lamport 甚至写了一篇论文《Paxos Made Simple》,但仍然难以理解。
Paxos 的实现难点:Prepare 和 Accept 阶段的协调、多数派的判断、Leader 选举、日志复制、故障恢复。
Paxos 的开源实现:Google Chubby(基于 Paxos)、Apache ZooKeeper(基于 ZAB,类似 Paxos)、etcd(基于 Raft)。
Paxos vs Raft
Paxos 理论完备但实现复杂,Raft 简化了 Paxos,使其易于理解和实现。Paxos 允许多个 Proposer,Raft 只允许一个 Leader。Paxos 的日志可以不连续,Raft 的日志必须连续。
Paxos 适合作为理论研究的对象,Raft 适合作为工程实践的参考。
Paxos 的应用
Google Chubby:Google 的锁服务,用于 Google 内部的分布式协调。Chubby 使用 Paxos 保证元数据的一致性。
Google Spanner:Google 的全球分布式数据库,使用 Paxos 实现数据复制。
Apache ZooKeeper:Apache 的协调服务,使用 ZAB 协议(类似 Paxos)。
Paxos 是共识算法的基石,虽然难以理解,但其思想影响了后续的共识算法设计。理解 Paxos 有助于理解其他共识算法。