我想了解three-phase commit如何避免阻止
考虑以下两种失败情况:
场景1:在阶段2中,协调器向所有队列发送预提交消息,并从队列A以外的所有队列获得确认。网络问题阻止队列A接收协调器的预提交消息。群组A超时等待预提交消息并选择中止。然后协调员和队列A都崩溃了。
场景2:协议到达阶段3.协调器向队列A发送doCommit消息。但在它发送更多doCommit消息之前,协调器崩溃。群组A提交其部分事务然后崩溃。
据我所知,其余队列在场景1和场景2结束时具有完全相同的状态。因此,当恢复协调员介入时,如何从剩余队列中找出我们是否在场景1和中止或我们在场景2中提交并因此避免阻塞?
答案 0 :(得分:9)
三阶段提交并不神奇;它比两阶段提交更有弹性。特别是,3PC可以抵御单点故障,但不是所有类型的多点故障。问题中的两个场景都提出了两点失误。换句话说,问题的前提是错误的;它要求更多的3PC而不是它的能力。
为了进一步阅读,这里有一篇关于这个主题的论文摘要Analysis and Verification of Two-Phase Commit & Three-Phase Commit Protocols, by Muhammad Atif的一句话,以激发你的胃口:
我们也将我们的方法应用于其“修正”变体,即三阶段 提交协议(3PC)并证明它同时是错误的 网站失败
我发现这篇论文为文献提供了立足点。如果你想钻研,那么这个主题就不算少了。
答案 1 :(得分:6)
在两阶段提交中,协调器向所有参与者(节点)发送准备消息并等待他们的答案。协调员然后将他们的答案发送到所有其他站点。在提交或中止交易之前,每个参与者都会等待协调员的这些答案。
两阶段提交协议也有一个限制,因为它是blocking protocol
。例如,参与者将在等待来自协调器的消息时阻止资源进程。如果由于任何原因失败,参与者将继续等待并且可能永远不会解决其交易。因此可以无限期地阻止资源。另一方面,协调员也会在等待参与者的回复时阻止资源。在这种情况下,协调员也可以阻止
肯定如果没有收到参与者的确认。
然而,三阶段协议引入了称为pre-commit
的第三阶段。这样做的目的是“消除已经承诺并等待协调员全球中止或提交消息的参与者的不确定期。
When receiving a pre-commit message, participants know that all others have voted to commit.
If a pre-commit message has not been received the participant will abort and release any blocked resources.
答案 2 :(得分:5)
在方案1中:
恢复期间: 除A之外的所有队列都将处于PRECOMMIT状态。这告诉恢复节点所有同类群组都已投票进行提交并向前移动。所以A和协调员应该处于PRECOMMIT状态。由于这是非最终状态,因此交易中止。
在方案2中:
恢复期间: 除A之外的所有队列都将处于PRECOMMIT状态。这告诉恢复节点所有同类群组已投票支持提交并向前移动。但是由于A收到了doCommit消息,因此它处于COMMITTED状态。如果没有发生崩溃,恢复将要求所有同类群组提交,因为至少有一个群组已经提交。由于发生崩溃(A崩溃),恢复节点看不到具有提交状态的实时队列,因此它推断出没有队列获得了doCommit消息。因此,交易将被中止,并且将要求所有群组释放资源。
当A从崩溃中返回并开始恢复时,它会发现所有其他同类群组中止了该事务,它也将中止该事务。
state chart http://regal.csep.umflint.edu/~swturner/Classes/csc577/Online/Chapter07/Images/07-21.jpg
答案 3 :(得分:0)
帮助我理解非阻塞属性的事情是认识到,在第一轮消息之后,两个协议基本上处于相同状态;所有参与者都同意可以提交并等待确认。
现在,请考虑参与者在第一轮回答“可以提交”后知道的事情。
继续前进,在3PC中进行第二轮消息和确认之后,我们可以确保所有参与者都知道要做出集体决定。
这意味着协议中永远不会有参与者进行提交动作而其他参与者无法预期的时间。