我相信三阶段提交是一个更好的方法。不幸的是,我还没有发现任何人实施这样的技术。
http://the-paper-trail.org/blog/consensus-protocols-three-phase-commit/
这里有上述文章的主要部分:
与2PC的主要困难是,一旦提交已决定由统筹制作,并传达给一些副本,复制品会直接前进并根据提交语句执行操作,而不检查每个其他副本是否收到该消息。然后,如果提交的副本与协调者一起崩溃,那么系统无法告诉交易的结果是什么(因为只有收到消息的协调员和副本肯定知道)。由于事务可能已经在崩溃的副本上提交,协议不能悲观地中止 - 因为事务可能具有无法撤消的副作用。同样,该议定书也不能乐观地强制交易承诺,因为最初的投票可能是堕胎。
这个问题 - 大部分情况 - 通过增加一个额外的阶段到2PC来绕过,毫不奇怪,给我们一个三阶段提交协议。这个想法很简单。我们打破2PC的第二阶段 - '承诺' - 分成两个子阶段。首先是“准备提交”阶段。当协调员在第一阶段收到一致的“是”票时,协调员会将此消息发送给所有副本。在接收到这些消息后,副本进入可以提交事务的状态 - 通过获取必要的锁等等,但最重要的是不做任何以后无法撤消的工作。然后他们回复协调员,告诉它已收到“准备提交”的信息。
此阶段的目的是将投票结果传达给每个副本,以便无论哪个副本死亡都可以恢复协议的状态。
该协议的最后阶段与2PC中的原始“提交或放弃”阶段几乎完全相同。如果协调员收到所有副本提交的“准备提交”消息的确认,则继续提交事务是安全的。然而,如果交付没有得到确认,协调员不能保证协议状态在它发生崩溃时能够被恢复(如果你容忍固定数量的故障,则协调器可以在接收到f + 1后继续确认)。在这种情况下,协调员将中止交易。
如果协调器在任何时候都应该崩溃,恢复节点可以接管事务并从任何剩余的副本中查询状态。如果已提交事务的副本已经崩溃,则我们知道每个其他副本都收到了“准备提交”消息(否则协调器不会移动到提交阶段),因此恢复节点将会能够确定交易能够被执行,并且安全地将协议安排在其结论之上。如果有任何副本向恢复节点报告尚未收到“准备提交”的副本,恢复节点将知道该事务没有在任何副本上提交,因此能够悲观地中止或重新运行协议从一开始就。
那么3PC是否解决了我们所有的问题?不完全,但接近。在网络分区的情况下,车轮相当不错 - 想象一下,所有收到“准备提交”的副本位于分区的一侧,而那些不在另一侧的副本。然后这两个分区将继续与分别提交或中止事务的恢复节点,并且当网络合并时,系统将具有不一致的状态。所以3PC和2PC一样有可能不安全的运行,但总是会取得进展并因此满足其活性特性。 3PC不会阻止单节点故障的事实使得它对于高可用性比低延迟更重要的服务更具吸引力。
这个答案提出了[网络可靠]这个危险的假设(https://queue.acm.org/detail.cfm?id=2655736)。 –
我不知道你在做什么。如果在第一阶段发生网络中断,TM将无法连接到其中一个RM并因致命错误而中止交易,最终告知所有RM在他们重新联机时中止。在第二阶段,它将继续轮询RM,直到网络恢复正常,此时它将发出确认提交。同样,2PC不保证提交,它只是保证事务不会失败,没有应用程序意识到它。 – ConcernedOfTunbridgeWells
如果TM在收到所有投票提交后崩溃,但在发送最终提交/放弃之前会怎么样?然后每个人都拿着锁,等待投票。而且你不能超时,有些节点可能会提交而其他节点会超时并中止。如果你有一个同步可靠的网络,并且没有节点崩溃,并且你有实时操作系统,这样你就可以在有限的时间内保证进度,那么2PC就可以工作。通常,我们没有这些属性。 –