Paxos分布式一致性算法详解

Paxos 分布式一致性算法详解

目录


一、Paxos 算法是什么

Paxos 算法是由 Leslie Lamport 于 1990 年提出的一种基于消息传递、具有高效容错特性的分布式一致性算法,是目前公认的解决分布式一致性问题最有效的算法之一。

核心思想

在一个可能发生消息丢失、延迟、重复的分布式环境中,如何让多个节点就某个提案(Proposal)达成一致。

通俗理解

Paxos = 在"不靠谱"的环境里,让一群人靠谱地达成一致的一套规则。

  • "不靠谱的环境" = 网络可能丢包、延迟、重复,机器可能宕机
  • "一群人" = 分布式系统里的多个节点
  • "达成一致" = 所有节点最终认可同一个结果
  • "一套规则" = Paxos 算法的两阶段流程

生活类比

假设你们公司有 5 个合伙人,现在要决定"今年年会去哪里开"。

规则是:超过半数(至少3个人)同意,才算定下来。

  • 理想情况:大家坐一间屋里开会,很快投票决定
  • 现实情况:5个合伙人分散在5个城市,只能靠发微信沟通
    • 微信可能延迟(消息半小时才到)
    • 微信可能丢失(对方根本没收到)
    • 有人可能不回消息(在忙/手机没电)
    • 甚至有人可能故意捣乱(发假消息)

问题:怎么保证大家最终能达成同一个决定?而且一旦定了,就不能再变了?


二、Paxos 中的三种角色

Paxos 算法定义了三种角色,实际中一个节点可以同时扮演多个角色:

  1. Proposer(提案者):负责提出提案(value),发起投票
  2. Acceptor(接受者):负责对提案进行投票,可以接受或拒绝提案
  3. 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票,过半数)
  • "去丽江"就定了!

关键点解读

  1. 为什么 A 想提三亚却最终提了丽江?

    • 因为 D 已经答应过别人"去丽江"了
    • 为了不推翻已有的决定,A 必须跟着提"丽江"
    • 这就是 Paxos 的"尊重大多数已有决定"机制
  2. 为什么 E 没回消息也能达成一致?

    • 因为只要超过半数(3票)同意即可
    • 5个节点中,3个同意就够了,不需要所有人
  3. 为什么一旦定了就不变?

    • 后续任何新提案,编号必须更大
    • 新提案者在 Prepare 阶段会"问一圈"
    • 只要超过半数节点已经接受了"丽江",新提案者就一定能看到这个决定
    • 新提案者只能跟着提"丽江",无法改变结果

四、Paxos 的关键特性

两条铁律

铁律1:编号大的提案"更有话语权"

每个提案都有一个唯一且递增的编号(相当于"优先级")。

  • 每个人先收到一个编号为 5 的提案,他可以答应
  • 但如果后来又收到编号为 3 的提案,他可以直接忽略
  • 承诺:我既然答应了编号 5 的,就再也不搭理比 5 小的提案了

→ 解决了"反悔"和"乱序"的问题

铁律2:两阶段走,先"问一圈"再"正式提"

第一步(试探)

"我有个编号5的提案,大家最近有没有答应过别人?有的话告诉我你们答应的是什么。"

  • 如果大多数人说"我们都没答应过别人",你才进入第二步
  • 如果大多数人说"我们已经答应了编号6的提案,内容是去丽江",那你不能再提自己的了,必须跟着提"去丽江"

→ 解决了"同时提议冲突"的问题

第二步(正式提交)

"好,那我正式提议:编号5,内容是去三亚/丽江,大家接受吗?"

  • 超过半数接受 → 就定了
  • 没超过半数 → 换个更大的编号重新来

算法特性

  1. 多数派原则(Quorum):只要超过半数节点存活且可通信,算法就能正常工作
  2. 提案编号唯一且递增:保证提案的有序性
  3. 承诺机制:Acceptor 一旦承诺不对更小编号的提案投票,就必须遵守
  4. 安全性(Safety)
    • 只有被提出的 value 才能被选定
    • 只有一个 value 被选定
    • 一个节点只能学习到已经被选定的 value
  5. 活性(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 就是一套"投票规则",在网络不靠谱、机器可能挂的情况下,保证一群机器最终能做出同一个决定,而且一旦决定了就不会变。

就像民主投票制度一样——可能过程有点慢、有点繁琐,但能保证最终结果是公平且一致的。

本质

让分布式系统像单机一样可靠。


参考资料

posted @ 2026-07-19 13:01  SeiunSky  阅读(12)  评论(0)    收藏  举报