Paxos分布式一致性算法详解
Paxos 分布式一致性算法详解
目录
一、Paxos 算法是什么
Paxos 算法是由 Leslie Lamport 于 1990 年提出的一种基于消息传递、具有高效容错特性的分布式一致性算法,是目前公认的解决分布式一致性问题最有效的算法之一。
核心思想
在一个可能发生消息丢失、延迟、重复的分布式环境中,如何让多个节点就某个提案(Proposal)达成一致。
通俗理解
Paxos = 在"不靠谱"的环境里,让一群人靠谱地达成一致的一套规则。
- "不靠谱的环境" = 网络可能丢包、延迟、重复,机器可能宕机
- "一群人" = 分布式系统里的多个节点
- "达成一致" = 所有节点最终认可同一个结果
- "一套规则" = Paxos 算法的两阶段流程
生活类比
假设你们公司有 5 个合伙人,现在要决定"今年年会去哪里开"。
规则是:超过半数(至少3个人)同意,才算定下来。
- 理想情况:大家坐一间屋里开会,很快投票决定
- 现实情况:5个合伙人分散在5个城市,只能靠发微信沟通
- 微信可能延迟(消息半小时才到)
- 微信可能丢失(对方根本没收到)
- 有人可能不回消息(在忙/手机没电)
- 甚至有人可能故意捣乱(发假消息)
问题:怎么保证大家最终能达成同一个决定?而且一旦定了,就不能再变了?
二、Paxos 中的三种角色
Paxos 算法定义了三种角色,实际中一个节点可以同时扮演多个角色:
- Proposer(提案者):负责提出提案(value),发起投票
- Acceptor(接受者):负责对提案进行投票,可以接受或拒绝提案
- Learner(学习者):负责学习已经达成一致的提案结果
三、Paxos 的工作机制(具体例子)
通俗易懂的例子
5个节点 A、B、C、D、E,A 想提议"去三亚":
第一步:试探(Prepare 阶段)
A 先发消息"问一圈":
- A 给 B、C、D、E 发:"编号5,你们最近答应过啥?"
- B 回:"没答应过任何提案"
- C 回:"没答应过任何提案"
- D 回:"我之前答应过编号3的,内容是去丽江"
- E 没回消息(网络问题)
- A 收到了 B、C、D 的回复(3票,过半数了)
第二步:正式提交(Accept 阶段)
A 根据回复决定最终提案内容:
- A 发现最大的已接受提案是编号3的"去丽江",所以 A 不能再提三亚了,必须提丽江
- A 给 B、C、D、E 发:"编号5,内容去丽江,接受吗?"
- B、C、D 都接受了(3票,过半数)
- "去丽江"就定了!
关键点解读
-
为什么 A 想提三亚却最终提了丽江?
- 因为 D 已经答应过别人"去丽江"了
- 为了不推翻已有的决定,A 必须跟着提"丽江"
- 这就是 Paxos 的"尊重大多数已有决定"机制
-
为什么 E 没回消息也能达成一致?
- 因为只要超过半数(3票)同意即可
- 5个节点中,3个同意就够了,不需要所有人
-
为什么一旦定了就不变?
- 后续任何新提案,编号必须更大
- 新提案者在 Prepare 阶段会"问一圈"
- 只要超过半数节点已经接受了"丽江",新提案者就一定能看到这个决定
- 新提案者只能跟着提"丽江",无法改变结果
四、Paxos 的关键特性
两条铁律
铁律1:编号大的提案"更有话语权"
每个提案都有一个唯一且递增的编号(相当于"优先级")。
- 每个人先收到一个编号为 5 的提案,他可以答应
- 但如果后来又收到编号为 3 的提案,他可以直接忽略
- 承诺:我既然答应了编号 5 的,就再也不搭理比 5 小的提案了
→ 解决了"反悔"和"乱序"的问题
铁律2:两阶段走,先"问一圈"再"正式提"
第一步(试探):
"我有个编号5的提案,大家最近有没有答应过别人?有的话告诉我你们答应的是什么。"
- 如果大多数人说"我们都没答应过别人",你才进入第二步
- 如果大多数人说"我们已经答应了编号6的提案,内容是去丽江",那你不能再提自己的了,必须跟着提"去丽江"
→ 解决了"同时提议冲突"的问题
第二步(正式提交):
"好,那我正式提议:编号5,内容是去三亚/丽江,大家接受吗?"
- 超过半数接受 → 就定了
- 没超过半数 → 换个更大的编号重新来
算法特性
- 多数派原则(Quorum):只要超过半数节点存活且可通信,算法就能正常工作
- 提案编号唯一且递增:保证提案的有序性
- 承诺机制:Acceptor 一旦承诺不对更小编号的提案投票,就必须遵守
- 安全性(Safety):
- 只有被提出的 value 才能被选定
- 只有一个 value 被选定
- 一个节点只能学习到已经被选定的 value
- 活性(Liveness):最终一定会有一个 value 被选定(在合理的超时和重试机制下)
五、Paxos 的业务场景
核心价值
Paxos 解决的是"信任问题":在分布式系统里,你不能相信任何一台机器(它可能坏),也不能相信网络(它可能丢包),你只能相信"超过半数机器的共同决定"。
场景一:银行转账(分布式数据库)
背景:你的账户余额存在 3 个副本(A、B、C 节点),防止某台机器坏了数据丢失。
业务操作:你转账 1000 元,余额从 10000 变成 9000。
❌ 没有一致性保证会怎样?
- A 节点写成了 9000
- B 节点因为网络抖动,没收到,还是 10000
- C 节点写成了 9000
- 结果:你查余额的时候,问到 B 节点显示 10000,问到 A 节点显示 9000
- 你懵了:我到底转没转成功?
更严重的:
- 你以为没转成功,又转了一次 → 重复扣款
- 或者 B 节点后来才收到消息,又把余额覆盖回 10000 → 钱凭空多出来了
✅ 有 Paxos 保证会怎样?
- 转账这个操作必须经过 3 个节点中超过半数(2个)确认才算成功
- 一旦 2 个节点确认了"9000"这个结果,它就被"选定"了,再也不会变
- 即使 B 节点一开始没收到,它恢复后也会去"学习"已经选定的结果(9000),自动对齐
- 你查任何节点,看到的余额都是一致的 9000
实际案例:OceanBase、TiDB 等分布式数据库的底层就是这套逻辑。
场景二:秒杀抢购(分布式锁)
背景:iPhone 最后一台,10 万人同时抢。后台有 100 台服务器处理请求。
业务操作:决定这台 iPhone 卖给谁。
❌ 没有一致性保证会怎样?
- 服务器 A 把 iPhone 卖给了张三
- 服务器 B 同时把同一台 iPhone 卖给了李四
- 结果:一台 iPhone 卖给了两个人(超卖)
- 电商平台血亏
✅ 有 Paxos 保证会怎样?
- 所有服务器必须先"达成一致":这台 iPhone 到底卖给谁
- 假设张三的请求先到达,Paxos 让超过半数的服务器同意"卖给张三"
- 这个决定一旦达成,就不可更改
- 即使后来李四的请求到达,服务器们也会回复:"对不起,已经卖给张三了"
- 绝对不可能出现超卖
实际案例:Google Chubby 分布式锁、ZooKeeper 的选举和锁机制。
场景三:配置中心更新
背景:一个大型系统有 1000 台机器,所有机器读同一份配置(比如限流阈值 = 1000 QPS)。
业务操作:运维把限流阈值从 1000 改成 2000。
❌ 没有一致性保证会怎样?
- 运维发了一条"改成 2000"的消息
- 800 台机器收到了,变成了 2000
- 200 台机器因为网络问题,没收到,还是 1000
- 结果:
- 一部分机器允许 2000 QPS
- 一部分机器只允许 1000 QPS,超过就限流
- 系统行为混乱,排查问题时根本不知道用的是哪份配置
✅ 有 Paxos 保证会怎样?
- 配置变更必须先经过 Paxos 算法"达成一致"
- 一旦超过半数节点接受了"改成 2000"这个提案,这个变更就被认定为"已提交"
- 即使那 200 台机器暂时没收到,它们恢复后也会自动学习到"最新已提交的配置是 2000"
- 所有机器最终都会用 2000 这个配置,且永远不会回退到 1000
实际案例:Apollo、Nacos 等配置中心。
场景四:集群选主(Leader 选举)
背景:一个数据库集群有 3 个节点(1主2从),主节点负责处理所有写请求。
业务操作:主节点挂了,要重新选一个主。
❌ 没有一致性保证会怎样?
- 从节点 A 宣布"我是新主"
- 从节点 B 也宣布"我是新主"
- 客户端不知道该把写请求发给谁
- 最严重的情况:两个主都接收写请求,各自处理各自的,最后数据彻底乱了(脑裂)
✅ 有 Paxos 保证会怎样?
- 选主过程就是一个 Paxos 提案:"让 A 当主"
- 必须超过半数(至少2个)节点同意,A 才能成为主
- 一旦 A 被选为主,这个决定不可更改
- 即使 B 后面想争,节点们会说:"我们已经选定 A 了,不接受其他提案"
- 整个集群永远只有一个主
实际案例:ZooKeeper 的 ZAB 协议、etcd 的 Raft 协议(Paxos 的简化版)。
场景五:分布式事务提交
背景:一个跨行转账操作,涉及两个银行的数据库,需要"要么都成功,要么都失败"。
业务操作:从 A 银行扣款,给 B 银行加款。
❌ 没有一致性保证会怎样?
- A 银行扣款成功了
- B 银行加款时网络断了
- 结果:钱从 A 扣了,但没到 B,钱凭空消失了
✅ 有 Paxos 保证会怎样?
- 事务的提交/回滚决定需要 Paxos 在多个节点间达成一致
- 要么超过半数节点同意"提交" → 两个操作都执行
- 要么没达到半数 → 回滚,两个操作都撤销
- 一旦决定"提交",就一定会提交到底,不会出现"扣了款却没加款"的中间状态
实际案例:Google Spanner、TiDB 的分布式事务。
业务价值总结
| 业务问题 | "做出同一个决定" | "一旦决定就不变" |
|---|---|---|
| 银行余额 | 所有副本数据一致 | 余额不会莫名回退 |
| 秒杀抢购 | 所有服务器都认为卖给张三 | 不会超卖 |
| 配置更新 | 所有机器用同一份配置 | 配置不会回退到旧版本 |
| 集群选主 | 只有一个 Leader | 不会出现脑裂 |
| 分布式事务 | 所有节点要么都提交要么都回滚 | 不会卡在中间状态 |
六、总结
Paxos 是分布式一致性领域的基石算法,它通过两阶段提交 + 多数派原则,在不可靠的网络环境中保证了数据的一致性。
核心价值
Paxos 就是一套"投票规则",在网络不靠谱、机器可能挂的情况下,保证一群机器最终能做出同一个决定,而且一旦决定了就不会变。
就像民主投票制度一样——可能过程有点慢、有点繁琐,但能保证最终结果是公平且一致的。
本质
让分布式系统像单机一样可靠。
参考资料
- Leslie Lamport. "The Part-Time Parliament." ACM Transactions on Computer Systems, 1998.
- Leslie Lamport. "Paxos Made Simple." ACM SIGACT News, 2001.
- Google Chubby: https://research.google.com/archive/chubby.html
- OceanBase: https://oceanbase.opensource.alibaba.com

浙公网安备 33010602011771号