在分布式系统中,当一个事务操作需要跨越多个分布式节点时,为了保持事务的ACID特性,就出现了“协调者(Coordinator)”来统一调度所有分布式节点的执行逻辑,而被调度的分布式节点则被称为“参与者(Cohort)”。协调者(Coordinator)负责调度参与者(Cohort)的行为,并最终决定这些参与者(Cohort)是否把事务真正进行提交。基于这个思想,衍生出2PC和3PC两种协议。
??2PC(Two-Phase Commit)为二阶段提交,为了分布式系统下所有节点操作事务能够保存原子性和一致性而设计的一种算法。主要应用在关系型数据库来完成分布式事务处理,利用该协议可以方便地利用协调者(Coordinator)进行统一的事务提交和回滚,从而能够有效的保证分布式数据一致性。
阶段一(提交请求阶段)
各参与者(Cohort)投票表明是否要继续执行接下来的事务提交操作:
阶段二(提交执行阶段)
协调者(Coordinator)会根据参与者(Cohort)的反馈情况来决定是否可以进行事务提交操作,可分为事务提交以及事务中断两种情况 。
事务提交:
当协调者(Coordinator)节点从所有参与者(Cohort)节点获得的对应的消息都为"Yes"时:
协调者(Coordinator)节点收到所有参与者(Cohort)节点反馈的"Ack"完成消息后,完成事务。
事务中断:
如果任一参与者(Cohort)节点在第一阶段返回的响应消息为"No",或者协调者(Coordinator)节点在第一阶段的询问超时之前无法获取所有参与者(Cohort)节点的响应消息时:
缺点
同步阻塞问题:执行过程中,所有参与者(Cohort)节点都是事务阻塞型。各个参与者(Cohort)在等待其他参与者响应的过程中,将无法进行其他任务操作;
单点故障:由于协调者(Coordinator)的重要性,一旦协调者(Coordinator)发生故障,参与者(Cohort)会一直阻塞下去。特别是在阶段二中,协调者(Coordinator)发生故障,那么所有的参与者(Cohort)还都处于锁定事务资源的状态中,而无法继续完成事务操作。
数据不一致:在阶段二中,当协调者(Coordinator)向参与者(Cohort)发送commit请求之后,发生了局部网络异常或者在发送commit请求过程中协调者(Coordinator)出现问题,将导致只有一部分参与者(Cohort)收到commit请求,以至于这部分参与者(Cohort)接到commit请求之后就会执行commit操作,而其他部分未接到commit请求的参与者(Cohort)则无法执行事务提交。于是整个分布式系统便出现了数据部一致性的现象。
不具备完善容错机制:任意一个节点的失败都会导致整个事务的失败。参与者(Cohort)宕机或者超时,都需要协调者(Coordinator)自身机制去判断或者协调者(Coordinator)在发出commit消息之后宕机,而唯一接收到这条消息的参与者(Cohort)同时也宕机了。那么即使协调者(Coordinator)通过选举协议产生了新的协调者,这条事务的状态也是不确定的,没人知道事务是否被已经提交。
??3PC (Three-Phase Commit)为了改进2PC中出现的同步阻塞、单点问题、脑裂以及保守的容错机制缺陷提出的三阶段提交协议,分为CanCommit、PreCommit和doCommit三阶段进行事务处理协议。如下图:
阶段二:PreCommit
??协调者(Coordinator)根据参与者(Cohort)的反应情况来决定是否可以继续事务的PreCommit操作。根据响应情况,有以下两种可能执行提交和中断事务:
执行提交:
协调者(Coordinator)从所有的参与者(Cohort)获得的反馈都是Yes响应,那么就会进行事务的预执行:
中断事务:
有任何一个参与者(Cohort)向协调者(Coordinator)发送了No响应,或者等待超时之后,Coordinator都没有接到参与者(Cohort)的响应,那么就中断事务:
阶段三:DoCommit
该阶段进行真正的事务提交,也可以分为以下两种情况执行提交和中断事务:
执行提交
中断事务:
协调者(Coordinator)正常,接收到参与者(Cohort)发送的反馈No响应,或者没有收到到Ack响应(可能是接受者发送的不是ACK响应,也可能响应超时),那么就会执行中断事务。
优缺点
原文:https://www.cnblogs.com/zery/p/14421553.html