4

我对 paxos 有一些困惑,特别是在数据库事务的上下文中:

在“paxos made simple”一文中,它说在第二阶段,提议者需要选择其中一个接受者之前接受过的具有最高序列号的值之一(如果不存在这样的值,则提议者可以自由选择建议选择原始值)。

问题:

  1. 一方面,我理解这样做是为了保持共识。但另一方面,我对实际价值感到困惑——“必须向接受者发送以前接受过的价值”有什么意义?

  2. 在数据库事务的上下文中,如果它需要提交一个新值怎么办?是否需要启动一个新的 Paxos 实例?

  3. 如果上述问题的答案是“是”,那么接受者如何重置状态?(据我了解,如果它不重置状态,提议者将被迫发送之前已接受的旧值之一,而不是自由提交新值。)

4

4 回答 4

2

“Paxos made simple”论文中有不同种类的 paxos。一个是Paxos(plain paxos,单度paxos,synod),另一个是Multi-Paxos。从工程师的角度来看,第一个是分布式的 write-once register,第二个是分布式的 append only log。

答案:

  1. 在 Paxos 的上下文中,实际值是成功写入一次写入寄存器的值,它发生在大多数接受者接受同一轮的值时。在论文中表明,新选择的值总是与以前的相同(如果它被选择的话)。所以要获得实际值,我们应该启动新一轮并返回新的成功写入的值。

    在 Multi-Paxos 的上下文中,实际值是添加到日志中的最新值。

  2. 使用 Multi-Paxos,我们只需在日志中添加一个新值。要读取当前值,我们读取日志并返回最新版本。在底层 Multi-Paxos 是一个 Paxos 寄存器数组。为了写入一个新值,我们将它与当前值的位置放在一个空闲寄存器中,然后我们用无操作填充先前的空闲寄存器。当两个寄存器包含相同的前一个值的两个不同的下一个值时,我们选择数组中位置最低的寄存器。

  3. 使用 Multi-Paxos 是可能的,而且很简单:我们只是通过一个免费的注册器开始新一轮的 Paxos。虽然普通的 Paxos 没有涵盖它,但我们可以“扩展”它并变成分布式变量而不是 dist。登记。我在“关于 Paxos 工作原理的备忘录”一文中描述了这个想法和证明。

于 2015-11-07T06:46:18.457 回答
1

我不会直接回答您的问题,而是尝试解释如何使用 Paxos 实现数据库事务,也许这将有助于理清问题。

首先要注意的是这里有两个“值”有问题。首先是数据库值,即正在修改的应用程序级数据。其次是“提交”/“中止”决定。对于基于 Paxos 的交易,共识“价值”是“提交”/“中止”决策。

关于 Paxos 共识的数据库事务要记住的重要一点是,Paxos 不保证事务中涉及的所有对等方都会真正看到共识决策。当需要这样做时,就像通常使用数据库一样,它留给应用程序来确保发生这种情况。这意味着一些对等点存储的状态可能落后于其他点,任何构建在 Paxos 之上的数据库应用程序都需要一些机制来处理这个问题。这可能非常复杂,并且都是特定于应用程序的,所以我将完全忽略所有这些,并专注于确保所有数据库副本中的简单多数同意数据库密钥 FOO 的修订版 2 的值,当然,最初设置为 BAR。

第一步是发送 FOO 的新值,假设它是 BAZ,它是预期的当前版本 1,以及 Paxos Prepare消息。当数据库副本收到此消息时,它们将首先查找 FOO 的本地副本并检查当前修订是否与准备消息中包含的预期修订匹配。如果它们匹配,则数据库副本将捆绑一个“Vote Commit”标志以及响应Prepare发送的Promise消息。如果它们不匹配,则将发送“投票中止”(修订检查可防止自应用程序上次读取值以来修改值的情况。

一旦事务驱动程序接收到一定数量的Promise消息及其关联的“Vote Commit”/“Vote Abort”值,它必须选择提议“Commit”或“Abort”。选择此值的第一步是遵循 Paxos 的要求,检查Prepare消息以查看是否有任何数据库副本(Paxos 术语中的Acceptor)已经接受了“提交”/“中止”决定。如果其中任何一个具有,则事务驱动程序必须选择与先前接受的最高提案 ID 关联的“提交”/“中止”值。如果他们没有,它必须自己决定。这是通过查看“投票提交”/“投票中止”来完成的s。如果存在法定人数的“Vote Commit”,则事务驱动程序可以提议“Commit”,否则必须提议“Abort”。

从那时起,所有标准的 Paxos 消息都会来回交换,直到就“提交”/“中止”决定达成共识。假设选择了“提交”,数据库复制者将分别将与 FOO 关联的值和修订更新为 BAZ 和 2。

于 2015-11-05T17:05:15.090 回答
0

这是我实现 raft 和阅读 ZAB 论文的经验。这是 PAXOS 的两个流行的化身。我还没有真正接触过简单的 paxos 或 multipaxos。

当客户端向集群中的任何节点发送提交时,它将将该提交重定向到领导者,然后领导者将提交消息发送到仲裁中的每个节点,当所有节点确认提交时,它将提交到自己的日志.

于 2017-03-30T17:40:18.697 回答
0

我写了一篇很长的博客,其中包含指向源代码的链接,主题是使用 Paxos 进行事务日志复制,如Paxos Made Simple论文中所述。在这里,我对您的问题进行简短的回答。博客文章和源代码显示了完整的图片。

一方面,我理解这样做是为了保持共识。但另一方面,我对实际价值感到困惑——“必须向接受者发送以前接受过的价值”有什么意义?

该值是客户端尝试在集群上运行的命令。在中断期间,最后一个领导者向所有节点传输的客户端值可能仅到达幸存的多数节点中的一个节点。新的领导者可能不是那个节点。新的领导者从至少一个幸存节点中发现客户端值,然后将其传输给幸存的多数节点中的所有节点。以这种方式,新领导者与死去的领导者合作完成它可能正在进行的任何客户工作。

在数据库事务的上下文中,如果它需要提交一个新值怎么办?是否需要启动一个新的 Paxos 实例?

在重建最后一个领导者选择的所选值的历史之前,它不能从客户端选择任何新命令。博客文章将此称为“领导者接管阶段”,在旧领导者崩溃后,新领导者正试图使所有节点完全更新。

实际上,无论选择了到达大多数节点的最后一个传输的领导者;新领导人无法改变这段历史。在接管阶段,它只是同步节点以使它们全部更新。只有当新的领导者完成这个阶段时,它才知道它完全更新了所有选择的值,它才能处理任何新的客户端命令(即处理任何新工作)。

如果上述问题的答案是“是”,那么接受者如何重置状态?

他们没有。被选择的值与任何节点得知该值已被选择之间存在差距。在数据库的上下文中,您不能“提交”该值(将其应用于数据存储),直到您“学习”了所选值。Paxos 确保选择的值永远不会被撤消。因此,在您得知该值已被选择之前,请不要提交该值。博客文章对此提供了更多详细信息。

于 2015-12-10T15:08:41.203 回答