分布式数据库事务上下文中的Paxos算法



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

在"paxos变得简单"的论文中,它在第二阶段中说,提出者需要选择其中一个接受者之前接受过的序列号最高的值之一(如果不存在这样的值,则提出者可以自由选择提出的原始值)。

问题:

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

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

  3. 如果以上问题的答案是"是",那么接受者如何重置状态?(根据我的理解,如果它不重置状态,提议者将被迫发送一个以前被接受的旧值,而不是自由提交任何新值。)

;帕克索斯制造了简单的";纸张一种是Paxos(普通Paxos、单度Paxos和synod),另一种是多Paxos。从工程师的角度来看,第一个是分布式一次写入寄存器,第二个是分布式仅追加日志。

答案:

  1. 在Paxos的上下文中,实际值是成功写入一次写入寄存器的值,当大多数接受者接受同一轮的值时,就会发生这种情况。在论文中表明,新选择的值将始终与以前的值相同(如果选择了它)。因此,为了获得实际值,我们应该启动新一轮并返回新的成功写入值。

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

  2. 使用Multi-Paxos,我们只需在日志中添加一个新值。为了读取当前值,我们读取日志并返回最新版本在低级别上,Multi-Paxos是一个Paxos寄存器阵列。为了写一个新值,我们把它和当前值放在一个空闲寄存器中,然后用no-op填充以前的空闲寄存器。当两个寄存器为相同的前一个值包含两个不同的下一个值时,我们选择数组中位置最低的寄存器

  3. 对于Multi-Paxos来说,这是可能的,也是微不足道的:我们只是在一个空闲寄存器上开始新一轮的Paxos。虽然普通的帕克索斯没有涵盖它,但我们可以"延伸";它并变成一个分布式变量,而不是dist.register。我在";关于帕克索斯如何工作的备忘录";邮递

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

首先要注意的是,这里有两个"价值观"存在疑问。首先是数据库值,即正在修改的应用程序级数据。其次是"提交"/"放弃"决定。对于基于Paxos的事务,一致的"值"是"提交"/"放弃"决策。

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

第一步是发送FOO的新值,比如说BAZ,它是预期的当前修订版1,以及PaxosPrepare消息。当数据库副本收到此消息时,他们将首先查找FOO的本地副本,并检查当前修订版是否与Prepare消息中包含的预期修订版匹配。如果它们匹配,数据库副本将捆绑一个"Vote Commit"标志,以及响应Prepare发送的Promise消息。如果它们不匹配,则将发送"投票中止"(修订检查可防止自应用程序上次读取值以来修改值的情况。在这种情况下允许覆盖可能会损坏应用程序状态)。

一旦事务驱动程序收到法定数量的Promise消息及其相关的"Vote Commit"/"Vote Abort"值,它必须选择提议"Commit"或"Abort"。选择该值的第一步是遵循Paxos的要求,即检查Prepare消息,以查看是否有任何数据库复制器(Paxos术语中的Acceptor)已经接受了"Commit"/"Abort"决定。如果其中任何一个有,则事务驱动程序必须选择与以前接受的最高提案ID相关的"提交"/"中止"值。如果没有,则必须自行决定。这是通过查看与Promise绑定的"Vote Commit"/"Vote Abort"值来完成的。如果达到"投票通信"的法定人数,事务驱动程序可以提出"提交",否则必须提出"中止"。

从那时起,所有标准的帕克索斯信息都会来回交换,直到就"提交"/"放弃"决定达成共识。假设选择了"提交",数据库复制器将分别将与FOO相关的值和修订更新为BAZ和2。

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

一方面,我理解它这样做是为了保持共识。但是另一方面,我对实际价值感到困惑-"必须向接受者发送已经在之前接受

该值是客户端试图在群集上运行的命令。在中断期间,由最后一个领导者传输到所有节点的客户端值可能只到达幸存多数中的一个节点。新的引线可能不是那个节点。新的领导者从至少一个幸存的节点中发现客户端值,然后将其传输到幸存的大多数节点中的所有节点。通过这种方式,新的领导者与已故的领导者合作,完成其可能正在进行的任何客户工作。

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

在重建上一个引线所选值的历史记录之前,它无法从客户端选择任何新命令。这篇博客文章称这是一个"领导者接管阶段",在旧领导者崩溃后,新领导者正试图让所有节点都全面更新。

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

如果以上问题的答案是"是",那么接受者如何回答重置状态?

他们没有。在正在选择的值和任何得知该值已被选择的节点之间存在差距。在数据库的上下文中,在"学会"所选值之前,您不能"提交"值(将其应用于数据存储)。Paxos确保所选的值永远不会被撤消。所以,在你知道价值已经被选择之前,不要承诺价值。这篇博客文章提供了更多的细节。

这是我实现raft和阅读ZAB论文的经验。这是PAXOS的两个普遍化身。我还没有真正进入简单的paxos或multipaxos。

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

最新更新