在 Paxos 的第二阶段,Proposer 必须在所有收到的反馈中,选择 已接受编号 () 最大 的那个 。这个规则看起来很奇怪:既然都是旧值,为什么大编号的优先级更高?
通过以下两个对比场景,我们可以看到如果不遵守这个规则,分布式一致性将如何崩溃。
背景设定
- 集群:5 个节点(A, B, C, D, E),达成共识需要 3 个节点。
- 目标:确保“一旦达成共识,就永不更改”。
场景一:如果不选最大的(导致共识被破坏)
假设我们违反规则,选择了一个小编号的旧值。
- 第一阶段:提议者 P1 () 成功让 A, B, C 接受了
Value="Apple"。- 结果:此时 “Apple” 已经达成了多数派共识。
- 第二阶段:提议者 P2 () 启动,它询问了 C, D, E。
- 反馈:
- 节点 C 回复:我接受过
[N=10, V="Apple"]。 - 节点 D 回复:我接受过
[N=5, V="Orange"](这是更早之前的残留)。
- 节点 C 回复:我接受过
- 错误决策:P2 觉得 “Orange” 更好看,违反规则选择了编号更小的 N=5。
- 反馈:
- 灾难发生:P2 发起
Accept(N=20, V="Orange"),并被 C, D, E 接受。- 后果:现在 C, D, E 认为共识是 “Orange”,而 A, B 认为共识是 “Apple”。
- 结论:一致性被破坏了! 已经定稿的 “Apple” 被无情地推翻了。
场景二:如果选最大的(保证一致性延续)
现在我们遵循规则,选择 最大 的旧值。
- 同样的背景:P1 () 已让 A, B, C 接受了
"Apple"。 - 同样的询问:P2 () 询问了 C, D, E,收到了
[N=10, V="Apple"]和[N=5, V="Orange"]。 - 正确决策:P2 发现 ,于是必须认领编号最大的
"Apple"。 - 结果:P2 发起
Accept(N=20, V="Apple")。- 后果:P2 实际上成了 P1 的“搬运工”,它帮助 P1 进一步巩固了 “Apple” 的地位。
- 结论:一致性得到了维护。 无论后来者编号多大,都会被强迫延续已经存在的最高编号的共识。
核心逻辑总结:为什么大编号代表“真相”?
在分布式系统的时序混乱中,编号的大小代表了逻辑上的“新旧”:
- 重叠性保证:任何一个新提议者的多数派,一定与之前已经达成共识的多数派有至少一个公共节点。
- 公共节点的职责:这个公共节点会把之前达成的共识(带着当时最大的编号)反馈给新提议者。
- 新提议者的职责:通过认领收到的反馈中“编号最大”的值,提议者实际上是在寻找 “全集群中目前最权威、最接近定稿” 的状态。
一句话总结: 认领“编号最大”的旧值,是为了确保后来者永远不会推翻前人已经达成的最高成就,从而实现分布式系统“万流归宗”的一致性。