简短的回答是,正确性的证明取决于每一轮每个节点的唯一数字。
一个直观的答案如下:
如果集群中的节点之间的提案编号不是唯一的,您可以让两个节点为相同的编号提出不同的值。在任意消息丢失的情况下,一些节点可能会接受一个值而另一些。潜在的新领导者将询问所有节点他们接受的最高值。然后它将返回相同数字的不同值的响应。然后它不能消除歧义并决定接下来要选择哪个值以使集群保持一致。使用唯一编号可确保每个值在每一轮中都有唯一编号。这确保了新领导者可以正确选择最高可接受的值。
人为场景:
A
具有领导者节点的五节点集群。网络失控了。节点B
认为它需要领导,因为它怀疑节点A
由于丢失消息而死亡。节点B
建议与上次使用的相同的数字A
。节点A
和B
实际上都已启动并尝试向其他节点传输不同的值。电源发生故障,所有节点都变暗,并且由于滚动电源故障导致网络中断,一些但不是所有消息都通过了。
接下来电源重新打开,但节点A
并E
保持死机。节点B
,C
和D
可以组成一个仲裁。节点C
提出一个新的高数字,并为最高接受值取回两个不同的值。一个来自A
,另一个来自B
。它现在必须在它们之间做出选择。哪个值可以保证使集群达到正确的一致性?
想象一下,在幸存的仲裁中,只有一个节点有A
值,但有两个节点有B
值。因此,假设我们猜测B
s 的值,但这可能是错误的。死节点A
,E
可能有A
s 值。节点A
碰巧在电源故障之前看到其值的大多数响应,因为它的消息恰好通过其他两个节点。价值是一笔付款,当它看到多数人的回应时,它会将钱从公司汇出。然而,幸存的仲裁决定A
s 值从未发生过,并使集群与B
s 值保持一致。
修复:
您需要做的就是对每个节点进行唯一编号,并将节点唯一编号编码为选票编号的最低有效位。然后每个节点使用它唯一的数字,并且可以轻松地生成一个新数字,该数字略高于集群中使用的最后一个最高数字。如果我们这样做,那么在任何一轮中只有一个值是最高接受的。
如果最后一个领导者得到多数响应,那么任何拥有多数席位的新领导者都将看到最后一个领导者使用的最高值。新的领导者不会与它将合作的最后一个领导者相矛盾。新领导人不需要知道死去的领导人是否真的看到了多数人的反应并采取了行动。相反,它会做出保守的选择,并假设它可能有并采取适当的行动。