Lamport的Paxos中的矛盾使得简单的纸

时间:2015-04-26 17:27:30

标签: algorithm distributed distributed-system paxos consensus

  

阶段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曾经回复的编号最大的准备请求的编号。

  1. P1向AB
  2. 发送'准备1'
  3. AB都答应P1承诺不接受任何编号小于1的请求。现在状态为:A( - : - ,1)B( - : - ,1)C( - : - , - )
  4. P1收到回复,然后卡住并且运行得很慢
  5. P2向AB
  6. 发送'prepare 100'
  7. AB都回应P2并承诺不接受任何编号小于100的请求。现在状态为:A( - : - ,100)B( - : - ,100)C( - : - , - )
  8. P2收到回复,选择一个值b并将'accept 100:b'发送给BC
  9. BC接收并接受接受请求,状态为:A( - : - ,100)B(100:b,100)C(100:b, - )。请注意,已选择提案100:b。
  10. P1恢复,选择值a并将'accept 1:a'发送给BC
  11. B不接受它,但C接受它,因为C从未承诺任何事情。状态是:A( - : - ,100)B(100:b,100)C(1:a, - )。选择的提案被放弃了,Paxos失败了。
  12. 我在这里错过了什么吗?感谢。

8 个答案:

答案 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唯一性要求。

迈克尔对Paxos问题的答案通常是正确的,但在这种情况下,我认为他犯了一个小错误,再次由于这个一个主要的误解 - 不会发生 - 而不是 - 更好的加重,在最原始的文件,问题。提议者不需要仅向那些使用Promise消息响应的对等体发送Accept消息。在向所有对等方发送Accept消息时,无论是否响应Promise消息,该算法都是正确的,只要提议ID对每个对等方保证唯一。尽管&#34; Paxos Made Simple&#34;纸... Paxos真的很简单。 它依赖于对前期要求的充分理解,而Unique Proposal Ids绝对是其中之一。

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的说法,实际上没有理由接受编号较低的提案。提案号码就像逻辑时钟,忽略旧消息是安全的。