为什么提议者发送一个与从接受者那里得到的值相同的接受请求?

Why does the proposer sends an accept request with the same value it got from the acceptor?

在paxos算法的第二阶段,如果acceptor已经选择了一个值,proposer会发出一个accept请求,它从acceptor那里得到了编号n和值v之前。我的问题是提议者为什么要这样做?因为一旦选择了一个值,它就是永久的并且不能更改,所以在这种情况下,提议者只是学习在准备请求的响应中发送的所选值。为什么它会要求接受一个已经接受的值?

选择的值必须与上届领导提出的值一致,否则选择的值可能会丢失。一种有用的思考方式是新提议者选择与旧提议者合作。如果它不协作,就会出现矛盾,我们会在整个分布式系统中出现不一致。

示例:

考虑节点 A、B 和 C 充当 multi-paxos 的所有角色。节点 A 是领导者并提出 V1。想象一下,网络出现故障,只有节点 A 和 B 能够通信,并且只有最少数量的消息可以让节点 A 知道选择了 V1。

当节点 A 收到节点 B 的消息时,它知道选择了 V1,因为它拥有多数(节点 A 和 B)。它向节点 B 和 C 发送消息,说明已选择该值,但是如本例中所述,没有进一步的消息从节点 A 传递。节点 A 执行业务操作,例如从金额为 V1 的银行帐户中支付钱。然后节点 A 崩溃。

节点 C 现在成为领导者,它不知道正确的银行账户余额,也不知道有关付款的任何信息。节点 B 知道 V1 中建议的付款,但不知道它是否被选中,因为它从未听过节点 A 的结果。因此节点 B 也不知道正确的银行账户余额。

你描述的机制正是节点 C 如何与死节点 A 合作选择值 V1。如果没有进一步的消息丢失,B 和 C 将进入一致的状态,他们同意从银行账户中支付的金额。

很明显,如果节点 C 不是通过节点 B 发现值 V1 而是要提出一些新值,我们就会有矛盾。银行账户将被破坏,因为付款 V1 不会反映在每个节点 B 和 C 的账户余额中。

讨论

在我的博客 post 上有关于您所询问的机制的详细讨论,其中描述了它 the leader takeover phase

我在上面描述的事件中假设了一些标准的实现细节。例如,有人可能会说 "don't move the money from the bank account without more messages to confirm that all nodes are aware the value is chosen"。然而,事实证明,Paxos 只需要最少数量的消息就可以保证安全,并且崩溃应该很少见。这意味着在实现 Paxos 时,在正常 运行 期间使用最少数量的消息通常是最佳的,并且在故障情况下依靠算法在整个系统中恢复一致的状态。

有趣的是,可以选择一个值,但没有活节点知道它。在上面的示例中,节点 A 运行足够长的时间以查看来自节点 B 的消息并在银行账户之间转移资金。然而,它可能在收到节点 A 的消息之前就崩溃了。除了节点 B 之外,它还会接受 V1,但是在节点 C 发现 V1 并也选择它之前,没有节点知道该值已被选择。

有趣的是,系统的客户端,观察银行账户的那些东西,或从银行账户接收付款的其他系统,也是分布式系统的一部分。如果示例中没有从银行账户进行付款,那么丢失 V1 将不是问题。然而,选择值的副作用是很正常的。第三方系统,或观察系统的用户网络浏览器,实际上是分布式系统的一部分。