简单介绍下2PC与3PC

二阶段提交协议和三阶段提交协议是经典的分布式一致性协议。

角色

协调者:统一调度分布式节点执行逻辑的组件

参与者:被调度的分布式节点

协调者负责调度参与者的行为,并最终决定这些参与者是否要把事务真正进行提交。

二阶段提交协议

我的理解:先问大家能不能干,大家收到后要是觉得能就开干。之后大家都说能就发消息让大家提交,有人说不能就发消息让大家回滚。

阶段一 提交事务请求(投票阶段)

1、 事务询问

协调者向所有参与者发送事务内容,询问是否可以执行事务提交操作,并开始等待各参与者响应

2、执行事务

各参与者节点执行事务操作,并将Undo和Redo信息计入事务日志中。

3、各参与者向事务协调者反馈事务询问的响应

若参与者成功执行了事务,则返回YES,否则NO

阶段二 执行事务提交

协调者根据参与者的反馈情况来决定最终会否可以进行事务提交操作。因此有以下两种情况

执行事务提交

协调者从所有参与者收到的都是YES

1、发送提交请求

协调者向所有参与者发送Commit请求

2、事务提交

参与者收到Commit请求后,执行事务提交操作,并在完成提交之后释放在整个事务执行期间占用的事务资源。

3、反馈事务提交结果

参与者在完成事务提交之后,向协调者发送ack消息

4、完成事务

协调者接受到所有参与者反馈的ack消息后,完成事务。

中断事务

如果有任何一个参与者反馈了NO响应,或在等待超时之后协调者尚无法接受到所有参与者返回的ack消息后,那么就会中断事务。

1、发送回滚请求

协调者向所有参与者节点发出Rollback请求

2、事务回滚

参与者接收到RollBack请求后,会利用其在阶段1中记录的Undo信息来执行事务回滚操作,并在完成回滚之后释放在整个事务执行期间占用的资源。

3、反馈事务回滚结果

参与者在完成事务回滚之后,向协调者发送ack消息

4、中断事务

协调者接受到所有参与者反馈的ack消息后,完成事务中断。

简单来说,2PC将事物的处理过程分为了投票和执行两个阶段,其核心对每个事务都采用先尝试后提交的处理方式,因此可以看作一个强一致性的算法。

优缺点

优点

原理简单,实现方便

缺点

同步阻塞(同步阻塞会极大地限制分布式系统的性能。在二阶段提交的执行过程中,所有参与该事务操作的逻辑都处于阻塞状态,各个参与者在等待其他参与者响应的过程中,将无法进行其他任何操作)

单点问题(协调者出问题,那么其他的参与者将会处于锁定事务资源的状态中,而无法继续完成事务操作)

数据不一致(二阶段如果Commit请求丢失部分参与者接到commit请求之后就会执行commit操作。但是其他部分未接到commit请求的机器则无法执行事务提交,会导致数据不一致)

太过保守(一阶段事务提交询问时如果参与者出问题,只能靠协调者的超时机制,太保守,任何节点的失败都会导致整个事务的失败)

三阶段提交协议

三阶段将二阶段提交协议的“提交事务请求”过程一分为二,形成了由CanCommit,PreCommit和doCommit三个阶段组成的事务处理协议。

阶段一:CanCommit

1、事务询问

协调者向所有参与者发送一个包含事务内容的CanCommit请求,询问是否可以执行事务提交操作,并开始等待各参与者的响应。

2、各参与者向协调者反馈事务询问的响应

参与者接收来自协调者的CanCommit请求后,如果自身认为可以顺利执行事务,那么会反馈Yes响应,进入预备状态,否则反馈No响应。

阶段二:PreCommit

根据各参与者的反馈情况决定是否可以进行事务的PreCommit操作,因此有两种情况

执行事务的预提交

1、发送预提交请求

协调者向所有参与者节点发出PreCommit请求,并进入Prepared阶段。

2、事务预提交

参与者接收到PreCommit请求后,会执行事务操作,并将Undo和Redo信息计入事务日志中。

3、各参与者向协调者反馈事务执行的响应

如果参与者成功执行了事务操作,那么就会反馈给协调者ACK响应,同时等待最终的指令:提交Commit或终止abort

中断事务

如任何一个参与者向协调者反馈了No响应,或者在等待超时之后,协调者尚无法接受到所有参与者的反馈响应,那么就会中断事务。

1、发送中断请求

协调者向所有参与者节点发出abort请求

2、中断事务

无论是收到来自协调者的abort请求,后而是在等待协调者请求过程中出现超时,参与者都会中断事务。

阶段三:doCommit

该阶段进行真正的事务提交,会存在以下两种可能的情况

执行提交

1、发送提交请求

如果协调者处于正常工作状态,并且它收到了来自所有参与者的ack响应,那么他将从预提交状态进入提交状态,并向所有的参与者发送docommit请求。

2、事务提交

参与者接收到doCommit请求,会正式执行事务提交操作,并在完成提交之后释放在整个事务执行期间占用的事务资源。

3、反馈事务提交结果

在完成事务提交之后,向协调者发送ACK确认信息

4、完成事务

协调者接收到所有参与者反馈的ack消息后,完成事务

中断事务

如果有参与者向协调者反馈了No响应或者等待超时后协调者仍无法收到所有参与者的响应,则中断事务。

1、发送中断请求

协调者向所有参与者节点发出abort请求

2、事务回滚

参与者接收到abort请求后,会利用其在阶段二中记录的Uodo信息来执行事务回滚操作,并在完成回滚之后释放在整个事务执行期间占用的资源。

3、反馈事务回滚结果

参与者在完成事务回滚之后,向协调者发送ack消息

4、中断事务

协调者接受到所有参与者反馈的ack消息后,完成事务中断。

需要注意的是,一旦进入阶段三,可能会存在以下两种故障。

  • 协调者出现问题

  • 协调者和参与者之间网络出现问题

无论出现那种情况,最终会导致参与者无法接受到来自协调者的doCommit或是abort请求,针对这样的情况,参与者都会在等到超时后,继续进行事务提交。

引入超时提交的依据:

其实这个应该是基于概率来决定的,当进入第三阶段时,参与者在第二阶段已经收到了PreCommit请求,那么协调者产生PreCommit请求的前提条件是他在第二阶段开始之前,收到所有参与者的CanCommit响应都是Yes。(一旦参与者收到了PreCommit,意味他知道大家其实都同意修改了)所以,一句话概括就是,当进入第三阶段时,由于网络超时等原因,虽然参与者没有收到commit或者abort响应,但是他有理由相信:成功提交的几率很大。

优缺点

优点

相对于二级段提交协议,三阶段提交协议的最大的优点就是降低了参与者的阻塞的范围(2PC一开始执行参与者就执行事务然后阻塞,3PC进过了CanCommit阶段之后在PreCommit阶段才开始执行事务阻塞,有了一次确认,不过说啥情况都阻塞,从而降低了阻塞范围),并且能够在出现单点故障后继续达成一致(超时提交)

缺点

三阶段提交协议在去除阻塞的同时也引入了新的问题,那就是参与者接收到precommit消息后,如果出现网络分区,此时协调者所在的节点和参与者无法进行正常的网络通信,在这种情况下,该参与者(出现问题的,而未出现问题的因为协调者超时会中断事务)依然会进行事务的提交,这必然出现数据的不一致性。

猜你喜欢

转载自www.cnblogs.com/wunsiang/p/12765123.html