我正在维基百科上阅读3阶段提交协议(http://en.wikipedia.org/wiki/Three-phase_commit_protocol),这是一个让我想到3PC失败的场景:
假设有两个参与者A和B以及一个协调员C:
1)C向A发送预先提交消息,在向A发送预先提交消息之前,A和C同时发生故障。 2)事务现在重新启动,B最终中止,因为没有来自A的回复.3)A提交事务,因为它已经获得了预先提交消息。
这也不是3PC应该解决的2PC中的原始问题吗? 3PC如何解决问题?我错过了什么感谢。
答案 0 :(得分:2)
<强>更新强>
在参与者收到协调员的doCommit消息之前,参与者是否未提交?
收到preCommit消息后,参与者将先等待,如果发生超时,他们将继续提交。
如果协调器在发送预先提交消息并且至少有一个参与者有预先提交消息后失败,则系统中的其余部分可以继续并提交,因为他们已经知道系统上的状态。
是的,一旦新协调员发现他们是已经收到preCommit消息的参与者,它就会向其他参与者重新发送preCommit消息。
答案 1 :(得分:0)
如果协调员在任何时候崩溃,恢复节点可以接管事务并从任何剩余的副本中查询状态。如果已提交事务的副本已崩溃,我们知道每个其他副本都收到“准备提交”消息(否则协调器不会移动到提交阶段),因此恢复节点将是能够确定事务是否能够被提交,并安全地将协议提交给它。如果任何副本向恢复节点报告尚未收到“准备提交”,则恢复节点将知道该事务尚未提交副本,因此将能够从一开始就悲观地中止或重新运行协议。
- 引自http://the-paper-trail.org/blog/consensus-protocols-three-phase-commit/
所以我认为新协调员将查询群组的状态,只有当所有实时群组都收到预提交消息时,新协调器才会发送do-commit消息;否则,交易将被中止。
答案 2 :(得分:0)
3PC只能容忍单点故障,而不是多点故障。实际上,为了确保3PC工作,必须满足以下三个条件:
没有网络故障(即没有网络分区,如果dest机器正在工作(没有崩溃),每条消息将在超时之前到达目的地)
最多一个参与者可能会失败(崩溃)。为了使其准确,如果协调员失败(崩溃),所有队列都不能失败
参与者机器可以区分超时和失败(这不是微不足道的,考虑它在超时后立即崩溃(即电动切断),在那里它无法向持久存储写任何东西以提醒自己它是恢复时超时而不是崩溃)
这些条件都不实用。所以我不认为3PC可以在现实世界中实现。