14

我正在使用Wikipedia中提供的文档在集群模拟器应用程序中实现 Paxos 。不幸的是,它为解释留下了几扇大门,并且没有提供关于关键实施问题的太多信息。它不清楚和不完整。

  • 假设一个集群分为 3 个区域,每个区域包含 3 个节点(总共 = 9 个节点)。如果区域之间的通信中断会发生什么?任何领导者都无法达到法定人数(即 5)。

Paxos不是要进入死循环了吗?如果一个人不能与至少一个法定人数的节点通信,我想一个人不应该启动 Paxos。

  • 在阶段 1b:'如果提案编号 N 大于任何先前的提案,则每个 Acceptor 承诺不接受小于 N 的提案,并将它最后接受的值发送给Proposer

“它接受的最后一个值”是什么?提案人之前是否有任何提案编号?在这种情况下,“实例”到底指的是什么?

  • 在阶段 1a:是否包含与 Prepare 消息达成一致的值,还是推迟到 Accept!信息?或者这很重要?

  • 在阶段 2a:'如果任何 Acceptor 已经接受了一个值,领导者必须选择一个具有最大提案编号 N的值'。

这里的价值是什么?是提案号吗?我不相信,但这句话不清楚。

  • 在阶段 2a:“否则,Proposer 可以自由选择任何值”。这是什么意思?有什么价值?对于提案编号?

  • Paxos 似乎依赖于不断增加的 N(提案编号)值来工作?这个对吗?

  • 维基百科条目没有讨论节点在开始参与 Paxos 之前应该设置的初始值。这些是什么?

PS:我没有足够的声誉来创建“Paxos”标签(任何志愿者?)

4

3 回答 3

18

什么是实例?

Paxos 中的命名法有点不直观。

  • 实例是选择一个值的算法。
  • 一轮是指提议者对 Phase 1 + Phase 2 的单次尝试。一个节点在Paxos实例中可以有多个轮。在所有节点中,每个实例的轮 ID 都是全局唯一的。这有时称为提案编号
  • 一个节点可以承担多个角色;最值得注意的是提议者和接受者。在我的回答中,我假设每个节点都承担两个角色。
  • 阶段 1 也称为准备阶段。
    • 在阶段 1a 中,Proposer 向 Acceptors 发送 Prepare!(roundId) 消息
    • 在阶段 1b,Acceptors 回复 Promise!(roundId, value) 或 PrepareNack!()
  • 阶段 2 也称为接受阶段。
    • 在阶段 2a 中,Proposer 向 Acceptor 发送 Accept!(roundId, value) 消息
    • 在阶段 2b 中,Acceptor 回复 Accepted!(...) 或 AcceptNack!()

假设一个集群分为 3 个区域,每个区域包含 3 个节点(总共 = 9 个节点)。如果区域之间的通信中断会发生什么?任何领导者都无法达到法定人数(即 5)。

Paxos 要求您至少可以获得一个仲裁(在您的情况下为 5 个节点)。使用您的三个区域的解决方案;在三个区域之间有两个网络分区是非常坏的消息。我还使用了一种 Paxos 版本,它可以将节点成员身份从一个实例更改为下一个实例。这对于分区和节点故障很有用。

Paxos不是要进入死循环了吗?

Paxos 的幼稚实现不能保证终止,因为多个节点可以跨越准备阶段。有两种方法可以解决这个问题。一种是在开始新的准备阶段之前进行随机退避。第二个是将所有请求路由到指定的领导者,该领导者充当提议者(领导者由 Paxos 实例选择。另见 Multi-paxos)

在阶段 1b:“如果提案编号 N 大于任何先前的提案,则每个 >>Acceptor 承诺不接受小于 N 的提案,并将它最后接受的值发送给 >>this instance to the Proposer”。

“它接受的最后一个值”是什么?提案人之前是否有任何提案编号?

当一个节点收到来自 Proposer 的 Accept!(roundId, value) 消息并且它没有承诺不接受该值(由于 Prepare!(higherRoundId) 消息)时,它会存储该值和 roundId(我会打电话给他们acceptedValueacceptedRoundId)。由于随后的 Accept!(...) 消息,它可能会覆盖这些。

当节点收到来自 Proposer 的 Prepare!(roundId) 消息时,它将 roundId 存储为promiseRoundId = max(roundId, promiseRoundId). 然后它向 Proposer 发送一个Promise!(acceptedRoundId, acceptedValue)回复。注意:如果节点没有收到 Accept!(...) 消息,它会回复Promise!(null, null).

在阶段 1a:是否包含与 Prepare 消息达成一致的值,还是推迟到 Accept!信息?或者这很重要?

没有必要发送它。我不。

在阶段 2a 中:“如果任何 Acceptor 已经接受了一个值,则领导者必须选择一个具有最大提案编号 N 的值”。

这里的价值是什么?是提案号吗?我不相信,但这句话不清楚。

该值是算法达成共识的实际数据。我会改写为

要开始接受阶段,提议者必须根据准备阶段的结果选择要接受的值。如果任何 Acceptor 回复了 Promise(roundId, value),Proposer 必须使用与最高 roundId 关联的值。否则,Proposer 只收到 Promise(null, null),并且可以选择任何值发送给接受者。

注意:这里的提案号和roundId是一样的。

在阶段 2a:“否则,Proposer 可以自由选择任何值”。这是什么意思?有什么价值?对于提案编号?

这是你想要达成共识的价值。这通常是跨分布式系统的状态更改,可能由客户端请求触发。

Paxos 似乎依赖于不断增加的 N(提案编号)值来工作?这个对吗?

维基百科条目没有讨论节点在开始参与 Paxos 之前应该设置的初始值。这些是什么?

Round ids(又名提案编号)应该增加,并且每个实例在所有节点上必须是唯一的。Paxos 论文假设您可以做到这一点,因为它很容易实现。这是一种在所有节点上产生相同结果的方案:

  1. 假设有 M 个节点参与一个 Paxos 实例。
  2. 按字典顺序对所有节点进行排序。index[node] 是此排序列表中节点的索引。
  3. roundId = i*M + index[node]其中 i 是该节点开始的第 i 轮(即 i 在每个 paxos 实例的每个节点中是唯一的,并且是单调递增的)。

或者在伪代码中(显然缺少一些主要优化):

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
    }
}
于 2012-04-14T06:46:59.990 回答
2

我发现以下文档更详细地解释了 Paxos。我已经相应地更新了维基百科条目。

我能找到的问题的答案是:

Paxos不是要进入死循环了吗?

Paxos 仅在至少有法定人数的节点可以相互通信时才有效(在我们的案例中为 5)。因此,如果一个节点不能与至少法定人数的节点通信,它不应该尝试 Paxos。

“它接受的最后一个值”是什么?

它是最后接受的命题编号和相应的值。

在这种情况下,“实例”到底指的是什么?

它指的是接受者。

是否包含与 Prepare 消息一致的值,还是推迟到 Accept!信息?或者这很重要?

该值不包含在 Prepare 消息中,它留给 Accept Request 消息。

这里的价值是什么?是提案号吗?我不相信,但这句话不清楚。

'否则,Proposer 可以自由选择任何值'。这是什么意思?有什么价值?对于提案编号?

如果acceptors已经接受了proposer的proposal,则可以返回相应的proposal number和value,否则什么都不返回。

第二个问题落下,因为维基百科条目具有误导性。可以为给定提案选择任意值,也可以从与较早接受的提案相对应的值中得出该值。

Paxos 似乎依赖于不断增加的 N(提案编号)值来工作?这个对吗?

是的。提议者 p 需要越来越多地对其提议进行编号。

维基百科条目没有讨论节点在开始参与 Paxos 之前应该设置的初始值。这些是什么?

节点应保留其最后接受的提案编号,并最终保留相应的值。他们应该坚持下去。首次连接时,给定提议者的初始提议编号应为空(或任何等效项)。

于 2011-05-01T19:50:39.973 回答
0
Paxos seems to rely on an increasing value of N (proposal number) to work? Is this correct?

每个提议者都有稳定的存储。每个提议者都会记住(在稳定存储中)它尝试发布的编号最高的提议,并以比它已经使用的任何提议编号更高的提议编号开始阶段 1。

于 2013-04-27T11:01:29.393 回答