7

我正在学习 Paxos 算法(http://research.microsoft.com/en-us/um/people/lamport/pubs/paxos-simple.pdf),有一点我不明白。

我们知道事件遵循及时的顺序,并且它发生在例如事件 1-5 和 10 已决定,但之后的 6-9 和 11 尚未决定时。在上面的论文中,它说我们只是用无操作值填充 6-9 之间的空白,并简单地记录从 11 开始的新事件。

所以在这种情况下,由于已经记录了事件 10,我们知道在 5 到 10 之间肯定发生了某些类型的事件,但由于某些故障而没有被 Paxos 记录。如果我们简单地填写 no-op 值,这些事件将在我们的记录中丢失。

更糟糕的是,如果正如我上面链接的论文所说,事件实际上是来自客户端的命令,那么中间缺少一些命令可能会使整个操作集非法(如果不能跳过任何命令或命令其中很重要)。

那么为什么 Paxos 为事件之间的间隙填充 no-op 值仍然是合法的呢?(如果整个记录集可能由于我上面提到的 no-op 值而无效。)另外,有没有更好的方法来从这些间隙中恢复而不是使用 no-op?

4

2 回答 2

5

这是一个多部分的答案。

提出无操作值是发现尚未到达节点的命令的方法。我们不是简单地用 no-op 命令填充间隙中的每个 slot:我们建议每个 slot 都用 no-op 命令填充。如果任何对等点已经接受了命令,它将在Prepare-ack消息中返回该命令,并且提议者将在接受轮中使用该命令而不是 no-op。

例如,假设一个节点位于临时网络分区的后面,并且无法与其他节点一起玩插槽 6-9。它知道它错过了学习槽 10 中的命令。然后它提出无操作来了解这些槽中决定的内容。

实际的实现也有一个带外学习协议来批量学习大量的转换。

在完全决定之前,命令不是命令;在那之前,它只是一个提议的命令。Paxos 是关于在来自多个客户端的竞争命令之间进行选择。客户端必须准备好拒绝他们的命令,因为选择了另一个客户端的命令。

实际的实现都是关于选择客户端命令的顺序。他们的世界观是预写日志的世界观,他们将命令放在该日志中。如果没有选择他们的命令,他们会在下一个插槽中重试。(有很多方法可以减少争用;Lamport 提到将请求转发给领导者,例如在 Multi-Paxos 中所做的。)

实际系统也有一些方法可以在提出命令之前知道命令是否无效;比如知道一组读和一组写。这很重要,有两个原因。首先,它是一个异步的多客户端系统,当客户端的命令到达服务器时,任何事情都可能发生变化。其次,如果两个并发命令不冲突,那么两者都应该能够成功。

于 2015-04-15T14:18:41.293 回答
0

系统模型允许命令(消息)无论如何都会被网络丢失。如果消息丢失,客户端最终会重试请求;所以放弃其中一些是可以的。如果客户端的命令必须按照客户端顺序执行,那么要么客户端只同步发送命令;要么 或者命令必须在库中的更高级别排序并在执行之前保存在某个客户端会话对象中。

AFAIK Zab 协议保证客户端顺序,如果您不想在更高级别实现它。

于 2015-04-14T08:52:41.470 回答