为什么 Paxos 需要两个阶段(prepare/promise
+ accept/accepted
)而不是一个阶段?也就是说,仅使用prepare/promise
部分,如果提议者已收到大多数接受者的回复,则选择该值。
问题是什么,是破坏安全还是破坏活力?
为什么 Paxos 需要两个阶段(prepare/promise
+ accept/accepted
)而不是一个阶段?也就是说,仅使用prepare/promise
部分,如果提议者已收到大多数接受者的回复,则选择该值。
问题是什么,是破坏安全还是破坏活力?
不遵循完整的协议会破坏安全性。
multi-paxos 的典型实现具有稳定状态模式,其中稳定的领导者流式Accept
传输包含新值的消息。只有当问题发生(leader 崩溃、停顿或被网络问题分区)时,新的 leader 才需要发布准备消息以确保安全。对此的完整描述在TRex一个开源 Paxos 库如何实现 Paxos 的文章中。
考虑以下TRex可以正确处理的崩溃场景:
A
, B
,C
带A
前导V1
给领导者A
A
处于稳定状态,因此发送accept(n, V1)
到节点B
和C
。网络开始出现故障,因此只B
看到消息并回复accepted(n)
A
看到响应并拥有多数{A,B}
,因此由于协议的安全证明,它知道该值是固定的。A
试图在它的服务器死机时将结果广播给每个人。只有发出消息的客户端应用程序才能V1
收到消息。想象这V1
是一个客户订单,在得知订单已修复后,客户端应用程序欠客户信用卡。C
在死亡的领导者上超时并尝试领导。它从来没有看到过价值V1
。它不能在不回滚订单的情况下任意选择任何新值,V1
但已经向客户收费。C
首先发出 aprepare(n+1)
并且 nodeB
用 来响应promise(n+1, V1)
。C
然后发出accept(n+1, V1)
并且只要剩余的消息通过节点B
并且C
将学习V1
选择的值。直观地说,Node通过选择' 的值来选择C
与死节点协作。所以直观地我们可以看到为什么必须有两轮。需要第一轮来发现是否有任何未完成的工作要完成。第二轮用于确定正确的值,以使系统内的所有进程保持一致。A
A
这并不完全准确,但您可以将两个阶段视为 1) 复制数据,然后 2) 提交数据。如果数据只是被复制到其他服务器,这些服务器将不知道是否有足够的其他服务器拥有数据以使其被认为是安全的。因此,有第二个阶段让服务器知道他们可以提交数据。
Paxos 比这要复杂一些,它允许它在任一阶段的故障期间继续运行。Paxos 证明的一部分是它是完全做到这一点的最小协议。也就是说,其他协议做更多的工作,要么是因为它们增加了更多的功能,要么是因为它们设计得不好。