阶段2.(a)如果提议者从大多数接受者收到对其准备请求(编号为n)的响应,则它向每个接受者发送一个接受请求,以获得编号为n且值为v的提议,其中v是答复中编号最高的提案的值,如果答复未报告任何提案,则为任何值。
正如文中所述,
提议者通过向某些接受者发送接受该提议的请求来发布提议。 ( 这不一定是响应初始请求的同一组接受器 。)“
但正如我的理解,如果我们将第2阶段改为:
如果提议者从大多数接受者收到对其准备请求(编号为n)的响应,则它会向 任意一组多数接受者发送接受请求 对于编号为n且值为v的提案,其中v是答复中编号最高的提案的值,如果答复未报告任何提案,则为任何值。
算法将失败,以下是一个示例。考虑到共有3个接受者ABC。我们将使用X(n:v,m)来表示接受者X的状态:提议n:v是X接受的最大编号提议,其中n是提议编号,v是提议的值,m是X曾经回复的编号最大的准备请求的编号。
我在这里错过了什么吗?感谢。
答案 0 :(得分:5)
您在步骤7中遗漏了某些内容。当C处理accept 100:b
时,它将其状态设置为C(100:b,100)
。 通过接受值,节点也承诺不接受早期值。
更新。我整个月都在考虑这个问题,因为我知道上述答案并非绝对正确。
我通过几个专有的和开源的paxos实现看了什么,他们都有OP提交的错误!
所以这里是正确答案,完全从 Paxos Made Simple 查看:
如果提议者从大多数接受者收到对其准备请求(编号为n)的响应,则会向 那些接受者 中的每个接收者发送接受请求提案编号为n,其值为v,其中v是答复中编号最高的提案的值,如果答复未报告提案,则为任何值。 (强调我的)
换句话说,提名者只能向{> 1>}收件人发送Accept
条信息
那么,这是Lamport论文中的一个矛盾吗?现在,我说是的。
如果你看一下Lamport的paxos样张,他会将Promises
视为accept
,就像我原来的回答所暗示的那样。但 Paxos Made Simple 中没有指出这一点。事实上,Lamport似乎非常痛苦地指出promise
不是accept
。
问题在于你将两种变体的较弱部分组合在一起;正如OP所做的那样,有几个实现。然后你遇到了这个灾难性的bug。
答案 1 :(得分:4)
向所有接受者广播接受请求当然没有问题。您无需将其限制为仅回复原始准备请求的那些。你已经在Lamport博士的写作中发现了一个罕见的措辞。
然而,您的反例中存在一个错误。首先,符号的定义如下:
THREE.Matrix4
表示接受者X的状态:提案X(n:v,m)
是X接受的编号最大的提案
但是在步骤7中,节点C具有状态n:v
,然后在步骤9中,它变为状态C(100:b,-)
。这不是有效的转换:在接受C(1:a,-)
之后,它应该保持在状态1:a
,因为C(100:b,-)
仍然是C 接受的编号最大的提案。
请注意,在100:b
之后接受1:a
是完全正常的,主要是因为网络是异步的,所以所有消息都可以延迟或重新排序而不会破坏任何内容,因此世界其他地方不能无论如何,先告诉哪个提案被接受了。
答案 2 :(得分:2)
NECROBUMP。即使两种变体中较弱的部分,也没有不一致性。让我们看一下问题中示例中的第9步:
"状态是A( - : - ,100)B(100:b,100)C(1:a, - )。选择的提案被放弃,Paxos失败了"
然而,在这一点上,我们拥有的是一个不确定的价值,因为没有多数接受的价值(我们必须最终选择'因为b在步骤6中被多数人接受。)
为了继续议定书,我们需要新的选票,最终将接受一些新的选票。该选票必须具有值' b',
证明:C将对任何准备请求作出回应(100,&#39; b&#39;),因为它接受的最高编号选票是(100,&#39; b&#39;),即使它< em> last 接受了投票(1,&#39; a&#39;)。 B也会回复(100,&#39; b&#39;)。因此,不再可能获得任何价值的多数票,但是&#39; b&#39;。
Lamport的语言是接受者将回复#34;该提案的数量小于其接受的n,如果有的话#34;
接受的答案混淆了#34;编号最高的&#34;最近接受了&#34;&#34;因为该示例显示接受者可以接受递减编号顺序的值。为了完全符合Lamport的协议,C必须记住它对(100,&#39; b&#39;)的响应,即使最新的&#34;接受它已经是(1,&#39; a&#39;)。
(话虽如此,如果许多实施方案不能正确执行此操作,我也不会感到惊讶,因此容易受到此问题的影响。)
答案 3 :(得分:1)
论文中确实存在歧义,这就是TLA +规范而不是论文应用于实现算法的原因。
接受值时,接受者必须再次更新其状态,即最近承诺的投票。从Paxos TLA+ specification可以很明显地看出来,请检查第2b阶段,其中接受者更新maxBal,然后与第1b阶段进行比较。
莱斯莉·兰普特(Leslie Lamport)处理了这个问题in his recent lecture,他解释说,这样做是专门为了使接受者的集合不同于承诺投票的节点的集合。
答案 4 :(得分:0)
拉姆达,
您的逻辑是合理的,但仅仅是因为您对Paxos算法的描述存在缺陷。这应该是预期的,因为Paxos在数学上已被证明是正确的,你指出的问题是经典的争用案例之一。我对古典Paxos文献的一个批评是,在我看来,这些论文没有说明这样一个事实,即算法的基本正确性要求是提案数不能被不同的方法重复使用。对等体即可。每次提出提案时,必须是唯一的,或者算法的正确性保证会被抛出窗口。如果允许重复使用,则会指出您指出的确切情况。如果你仔细阅读 very ,你会发现经典论文中提到了这一点,但它并没有在应有的程度附近受到压力。应该使用粗体,下划线和恼人的文本。
为了说明这一点,请将您的示例中的提案ID(也称为整数)的定义更改为(&#39; poposal number&#39;,&#39; proposer unique-id&#39; )而不仅仅是一个整数,其中排序定义为a>b if a.proposal_number > b.proposal_number or a.proposer_unique_id > b.proposer_unique_id
。您将看到您描述的问题消失,算法完全正确。您的示例完全方案描述了&#34;非案例&#34; Understanding Paxos的部分。我可能会补充一个部分,我纯粹是因为我发现自己对你指出的情景非常困惑。很容易错过古典文献中的提案ID唯一性要求。
Rakis
答案 5 :(得分:0)
C不能接受该提案,因为它还没有通过第1阶段。接受者接受了一个谷,接受者必须通过协议的两个阶段。
答案 6 :(得分:0)
如果接受一个值,节点也承诺不接受早期值,算法是正确的,但在论文中Lamport没有提到这个要求,对吗?
不需要上述条件。假设接受者承诺的最高投票是X.假设传入的接受消息具有选票号Y.如果Y&lt; X,我们知道Y必须被拒绝。如果Y> X,这意味着接受者没有收到Y的准备请求。这意味着,我们收到了无效的paxos消息。在这种情况下,应删除Y的接受消息。
唯一的例外是当Y == 0时。在这种情况下,由于0以下的选票无效,发布选票号为0的准备没有意义。因此,对于选票0可以跳过阶段1,并且提议者可以直接进入阶段2.在这种情况下,即当Y == 0时,接受者只有在没有接受值的情况下才能接受该值。这与您上面提出的内容相同,但仅在优化版Paxos中需要,在Y == 0时可以跳过阶段1。
IOWs,接受者接受值的唯一时间是Y == X.唯一的例外是Y == 0.在这种情况下,只有在接受者没有接受值时,接受者才能接受该值。
答案 7 :(得分:0)
我同意Ben Braun的大部分回答。
C接受(1,a)没关系,它不会改变所选择的值。让C接受(1,a),我们从学习者的角度来看待接受历史。
(100,b)被B和C接受 (1,a)被C
接受 选择(100,b),因为它被大多数受体接受。
此时,如果学习者获得完整的接受历史记录,则协议不需要继续,除非学习者失败或者学习者的消息丢失。这是我不同意Ben Braun的答案的地方。
但是,如果发布新提案,接受方应保持接受的提案的编号最高。
更新:我也同意Dave Turner的说法,实际上没有理由接受编号较低的提案。提案号码就像逻辑时钟,忽略旧消息是安全的。