我正在使用Wikipedia中提供的文档在集群模拟器应用程序中实现Paxos。不幸的是,它为解释留下了许多门户,并且没有提供有关关键实施问题的大量信息。目前尚不清楚和不完整。
假设群集分为3个区域,每个区域包含3个节点(总计= 9个节点)。如果区域之间的通信中断,会发生什么?任何领导者都无法达到法定人数(即5)。
Paxos不会进入无限循环吗?我猜如果一个人至少不能与法定数量的节点通信,就不应该启动Paxos。
在阶段1b中:“如果投标编号N大于任何先前的投标,则每个接受方承诺不接受小于N的投标,并将其在该实例中最后接受的值发送给投标人”。
什么是“它接受的最后一个价值”?是提案人以前提供的提案编号吗?
在这种情况下,“实例”到底指的是什么?
在阶段1a中:是否包含同意“准备”消息的值,或者将其推迟到“接受”!信息?还是有关系吗?
在阶段2a中:“如果任何一个接受者已经接受了一个值,则领导者必须选择一个具有最大投标编号N的值”。
这有什么价值?是提案编号吗?我相信不会,但是这句话还不清楚。
在阶段2a中:“否则,提议者可以自由选择任何值”。这是什么意思?有什么价值?对于提案编号?
Paxos似乎依赖于N的递增值(建议数)来工作?这样对吗?
维基百科条目没有讨论节点在开始参与Paxos之前应设置的初始值。这些是什么?
附注:我没有足够的声誉来创建“ Paxos”标签(有志愿者吗?)
最佳答案
什么是实例?
Paxos中的术语有点不直观。
实例是选择一个值的算法。
一轮回合是指提议者对阶段1 +阶段2的单次尝试。一个节点在Paxos实例中可以进行多次回合。在所有节点上,每个实例的回合ID全局唯一。有时称为提案编号。
一个节点可以扮演多个角色。最明显的是提议者和接受者。在我的回答中,我假设每个节点都担当这两个角色。
阶段1也称为准备阶段。
在阶段1a中,提议者将Prepare!(roundId)消息发送给接受者
在阶段1b中,接受方以Promise!(roundId,value)或PrepareNack!()答复。
阶段2也称为接受阶段。
在阶段2a中,提议者将Accept!(roundId,value)消息发送给受体
在阶段2b中,接受者以“接受!(...)”或“接受否!()”答复。
假设群集分为3个区域,每个区域包含3个节点(总计= 9个节点)。如果区域之间的通信中断,会发生什么?任何领导者都无法达到法定人数(即5)。
Paxos要求您至少可以达到法定人数(在您的情况下为5个节点)。解决三个区域的问题;在这三个区域之间具有两个网络分区是一个坏消息。我还使用了Paxos的版本,该版本可以将节点成员资格从一个实例更改为另一个实例。这对于分区和节点故障很有用。
Paxos不会进入无限循环吗?
不保证Paxos的幼稚实现会终止,因为多个节点可以跳过“准备”阶段。解决此问题的方法有两种。一种是在开始新的准备阶段之前获得随机补偿。第二种是将所有请求路由到指定的领导者,该领导者充当提议者(该领导者由Paxos实例选择。另请参见Multi-paxos)
在阶段1b中:“如果提案编号N大于任何先前的提案,则每个>> Acceptor都承诺不接受小于N的提案,并将其上一次对此>>实例接受的值发送给提案人”。
什么是“它接受的最后一个价值”?是提案人以前提供的提案编号吗?
当节点从提议者接收到Accept!(roundId,value)消息并且没有承诺不接受该值时(由于Prepare!(higherRoundId)消息),它将存储该值和roundId(我将称为acceptedValue
和acceptedRoundId
)。由于后续的Accept!(...)消息,它可能会覆盖这些内容。
当节点从提议者接收到Prepare!(roundId)消息时,它将roundId存储为promiseRoundId = max(roundId, promiseRoundId)
。然后,它将Promise!(acceptedRoundId, acceptedValue)
发送回建议者。注意:如果节点未收到Accept!(...)消息,则会以Promise!(null, null)
答复。
在阶段1a中:是否包含同意“准备”消息的值,或者将其推迟到“接受”!信息?还是有关系吗?
无需发送。我不。
在阶段2a中:“如果任何一个接受者已经接受了一个值,则领导者必须选择一个具有最大投标编号N的值”。
这有什么价值?是提案编号吗?我相信不会,但是这句话还不清楚。
该值是算法达成共识的实际数据。我将其改写为
要开始接受阶段,提议者必须根据准备阶段的结果选择要接受的值。如果有任何接受者以Promise(roundId,value)答复,则提议者必须使用与最高roundID相关联的值。否则,提议者仅收到Promise(null,null),并且可以选择任何值发送给接受者。
注意:此处的投标编号与roundId相同。
在阶段2a中:“否则,提议者可以自由选择任何值”。这是什么意思?有什么价值?对于提案编号?
这是您希望达成共识的价值。这通常是整个分布式系统的状态更改,可能是由客户端请求触发的。
Paxos似乎依赖于N的递增值(建议数)来工作?这样对吗?
维基百科条目没有讨论节点在开始参与Paxos之前应设置的初始值。这些是什么?
轮ID(又称提案编号)应该不断增加,并且在所有节点上每个实例都必须是唯一的。 Paxos论文假定您可以执行此操作,因为这很容易实现。这是在所有节点上产生相同结果的一种方案:
假设有M个节点参与Paxos实例。
按字典顺序对所有节点进行排序。 index [node]是此排序列表中节点的索引。roundId = i*M + index[node]
其中,i是该节点开始的第i轮(即,每个paxos实例的每个节点i都是唯一的,并且是单调递增的)。
或使用伪代码(显然缺少一些主要的优化):
define runPaxos( allNodesThisPaxosInstance, myValue ) {
allNodesThisPaxosInstance.sort()
offset = allNodesThisPaxosInstance.indexOf( thisNode )
for (i = 0; true; i++) {
roundId = offset + i * allNodesThisPaxosInstance.size()
prepareResult = doPreparePhase( roundId )
if (!prepareResult.shouldContinue?)
return
if (prepareResult.hasAnyValue?)
chosenValue = prepareResult.valueWithHighestRoundId
else
chosenValue = myValue
acceptResult = doAcceptPhase( roundId, chosenValue )
if (!acceptResult.shouldContinue?)
return
}
}
关于implementation - 有关Paxos实现的问题,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/5850487/