为什么Paxos需要两个阶段(prepare/promise
+ accept/accepted
)而不是一个阶段?也就是说,只使用prepare/promise
部分,如果提议者已经从大多数接受者那里收到回复,那么该值就是选择的。为什么Paxos是两个阶段
问题是什么,它是否会破坏安全性或活力?
为什么Paxos需要两个阶段(prepare/promise
+ accept/accepted
)而不是一个阶段?也就是说,只使用prepare/promise
部分,如果提议者已经从大多数接受者那里收到回复,那么该值就是选择的。为什么Paxos是两个阶段
问题是什么,它是否会破坏安全性或活力?
它打破了安全性,不遵循完整的协议。
多重paxos的典型实现具有稳定状态模式,其中稳定的前导码流包含新鲜值的消息Accept
。只有当问题发生时(领导者崩溃,摊位或由网络问题分区),新领导者才需要发布准备消息以确保安全。对此的完整描述在write-up of how 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
首先发出一个prepare(n+1)
节点B
回应promise(n+1, V1)
。C
然后发出accept(n+1, V1)
并且只要剩余的消息通过节点B
和C
得知将会知道值V1
被选中。直观上我们可以说,节点C
选择了通过选择A
的价值与死者节点A
合作。所以直观地我们可以看到为什么必须有两轮。第一轮需要发现是否有任何待完成的工作。第二轮用于修正正确的值,使系统内所有进程保持一致。
这并不完全准确,但您可以将两个阶段想象为1)复制数据,然后2)提交数据。如果数据只是复制到其他服务器上,那么这些服务器就不知道是否有足够的其他服务器拥有数据,以使其被认为是安全服务的。因此,有第二阶段让服务器知道他们可以提交数据。
Paxos比这个稍微复杂一点,它允许它在任一阶段的故障期间继续运行。 Paxos证明的一部分是,它完全是这样做的最小协议。也就是说,其他协议可以做更多的工作,或者是因为它们增加了更多的功能,或者因为它们设计不佳。