两阶段提交和三阶段提交的理解

两阶段提交和三阶段提交的理解

本文主要通过梳理流程说明2PC的缺点,并总结3PC的优点。

一、2PC流程及致命问题 
两阶段提交和三阶段提交的理解_第1张图片

如图所示,2PC的流程简要: 
1.协调者 参与者都是INIT状态,参与者等待消息。 
2.协调者进入prepare状态发送vote_request消息。 
3.协调者等待消息 
4.参与者收到消息,进入ready状态并发送vote_commit 
5.参与者等待消息 
6.协调者收到所有消息,从prepare变更为commit发送global_commit(或者发送abort)。协调者完毕 
7.参与者收到消息执行commit。 
参与者有两个状态:commit状态或abort状态。

WAIT是容易出问题的地方:一旦超时如何处理? 
WAIT 1(INIT状态等待):参与者自己abort事务 
WAIT 2(prepare状态等待):协调者可以多播abort命令中止 
WAIT 3(ready状态等待): 当参与者处于ready状态 难点!!超时的原因可能有三点 
1.协作者崩溃 没有发出global_commit。 
解决:持久化协作者状态。它在重启后会获取当前状态,若是prepare阶段,则直接abort;若是commit阶段则再次发送commit。 
2.参与者崩溃了 
解决:只有在参与者可互相通信的前提下才能解决。 
3.网络丢包 
解决:只有在参与者可互相通信的前提下才能解决。

参与者互通信解决超时问题: 
参与者P在某个阶段超时,检查另一个参与者Q的状态,以决定自己的状态。 
必须持久化参与者状态 
Q在commit、abort、init状态,则P只需要改为相应状态就行。 
Q在ready状态,检查其余,若都在ready状态,则必须阻塞等待协调者。因为很可能这时协调者是在commit状态下崩溃的,恢复后会执行commit,若参与者因为ready超时而终止,但协调者却认为已经commit了,则导致两者不一致!

综上所述,2PC的致命问题:超时导致进程阻塞以致资源无法释放

二、3PC如何解决阻塞问题 
两阶段提交和三阶段提交的理解_第2张图片 
如图所示,我们知道2PC所有问题都出在ready阶段,3pc在ready阶段后,加入了precommit阶段,以此解决了阻塞问题。我们分析下它是如何巧妙解决的。 
WAIT超时状态: 
WAIT 3:ready状态超时,参与者可直接abort。因为ready状态超时,其他参与者只能是ready、precommit、abort状态。 
WAIT 4:协调者precommit状态超时(还未发送perpare_commit ,参与者处于ready ),直接abort。原因同上。
WAIT 5:参与者precommit状态超时,直接commit。(有问题),这两个状态都代表了可以commit的意思! 
简而言之,precommit状态(预提交)给予双方一个凭证,可以在未commit前进行“反悔”。参与者部分ready、部分precommit可以直接abort不会影响最终一致性。参与者全部是precommit状态,则完全可以进行commit。

还是有问题:

如果一个参与者是percommit状态 ,则其他参与者 必然处于 ready percommit commit的一种,这三种状态下都可以commit!

但是如果集群里即有ready 又有percommit参与者,参与者在不知道其他参与者状态下,是无法进行决定的。

参考文献:分布式原理与泛型

你可能感兴趣的:(分布式)