分布式一致性协议:2PC与3PC

前言
 

在对一个分布式系统进行架构设计的过程中,往往会在系统的可用性和数据一致性之间进行反复的权衡,于是就产生了一系列的一致性协议和算法。其中最著名的就是二阶段提交协议(2PC)、三阶段提交协议(3PC)和 Paxos 算法。

在分布式系统中,每一个机器节点虽然都能够明确地知道自己在进行事务操作过程中的结果是成功或失败,但却无法直接获取到其他分布式节点的操作结果。因此,当一个事务操作需要跨越多个分布式节点的时候,为了保持事务处理的ACID特性,就需要引入一个称为“协调者(Coordinator)”的组件来统一调度所有分布式节点的执行逻辑,这些被调度的分布式节点则被成为“参与者(Participant)”。协调者负责调度参与者的行为,并最终决定这些参与者是否要把事务真正进行提交。基于这个思想,衍生出了二阶段提交协议(2PC)、三阶段提交协议(3PC)。
 
 

二阶段提交协议(2PC)
 

利用该协议能够非常方便地完成所有分布式事务参与者的协调,统一决定事务的提交或者是回滚,从而能够有效地保证分布式数据一致性,因此二阶段提交协议被广泛地应用在许多分布式系统中。

顾名思义,2PC就是将事务的提交过程分成了两个阶段来进行处理。过程如下

 
阶段一:准备阶段

协调者询问每个参与者事务是否执行成功,参与者反馈事务执行结果。

在这里插入图片描述
 
在这里插入图片描述
阶段二:提交阶段
 
提交阶段有两种可能

  • 如果事务在每个参与者上都执行成功,事务协调者发送通知让参与者提交事务;
  • 否则,只要有一个失败,协调者发送通知让所有参与者回滚事务。

需要注意的是,在准备阶段,参与者执行了事务,但是还未提交。只有在提交阶段接收到协调者发来的通知后,才进行提交或者回滚。

2PC的核心是对每个事务都采用先尝试后提交的处理方式,因此也可以将二阶段提交看作为一个强一致性的算法。
 
2PC 的优缺点分析
 
优点

  • 原理简单
  • 实现方便

缺点

  • 同步阻塞:所有事务参与者在等待其它参与者响应的时候都处于同步阻塞状态,无法进行其它操作,极大的限制了系统的性能。
  • 单点问题:协调者在 2PC 中起到非常大的作用,发生故障将会造成很大影响。特别是在阶段二发生故障,所有参与者会一直等待,无法完成其它操作。
  • 数据不一致:在阶段二,如果协调者只发送了部分 Commit 消息,此时网络发生异常,那么只有部分参与者接收到 Commit 消息,也就是说只有部分参与者提交了事务,使得系统数据不一致。
  • 太过保守:任意一个节点失败就会导致整个事务失败,没有完善的容错机制。

 
二阶段提交协议(2PC)
 
是2PC的改进版,其将二阶段提交协议的阶段一分成两个过程,形成了由CanCommit、PreCommit 和 do Commit 三个阶段组成的事务处理协议。

阶段一:CanCommit
 
协调者向参与者发送一个包含事务内容的CanCommit请求,参与者回馈 Yes 或者 No

阶段二:PreCommit
 
根据阶段一的反馈结果,有两种操作可能

  • 如果阶段一所有参与者都反馈了 Yes ,那么协调者给参与者发送 preCommit 请求,执行预提交。如果参与者成功执行了事务操作,那么就反馈 Ack,之后等待最终命令 :提交(commit)还是终止(abort)。
  • 只要有一个 No 反馈,或者等待超时,那么就会中断事务。协调者向所有参与者发出终止(abort)请求。

阶段三:doCommit
 

该阶段将进行真正的提交,也是两种可能

  • 协调者收到了所有参与者的 Ack 确认,那就全部正式提交
  • 否则,全部回滚。

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

  • 协调者出现问题
  • 协调者和参与者之间的网络出现故障。

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

 
3PC 的优缺点分析
 
优点:

相较于2PC,3PC最大的优点就是降低了参与者的阻塞范围,并且能够在单点故障后继续达成一致。

缺点:

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

猜你喜欢

转载自blog.csdn.net/u013568373/article/details/91489352