55:一致性协议:2PC,3PC与Paxos

172 阅读10分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第2天,点击查看活动详情

分布式系统各个节点无法直接获取其它节点的操作结果,因此当一个事务操作需要多个分布式节点参与时,为了保证事务的ACID,就需要一个称为“协调者“的组件来统一调度所有分布式节点的执行逻辑,被调度的结果称为“参与者”,由协调者决定参与者的事务是否真正进行提交。

2PC

Two-Phase Commit, 二阶段提交。目前绝大多数关系型数据库采用的分布式事务协议。利用该协议能非常方便的完成分布式事务参与者的协调,统一决定事务的提交和回滚。

执行过程

阶段一:提交事务请求,又称为投票阶段

  1. 事务询问:协调者向所有的参与者发送事务内容,询问是否可以执行事务提交操作,并开始等待各个参与者的响应
  2. 执行事务:各参与者执行事务,并将Undo和Redo信息记入事务日志
  3. 各参与者向协调者反馈事务询问的响应:如果参与者成功执行了事务操作,那么就反馈给协调者Yes响应,表示事务可以执行。如果参与者没有成功执行事务操作,那么就反馈给协调者No响应,表示事务不可以执行。

阶段二:执行事务提交

执行事务提交:所有参与者都反馈YES

  1. 发送提交请求:协调者向所有参与者阶段发送Commit请求
  2. 事务提交:参与者接到Commit请求后,正式提交事务
  3. 反馈事务提交结果:参与者向协调者ACK消息
  4. 完成事务:协调者接到所有Ack消息后,完成事务

中断事务:任一参与者反馈NO

  1. 发送回滚请求
  2. 事务回滚
  3. 反馈回滚结果
  4. 事务中断

以上就是2PC,即将事务的提交分为投票和执行两个阶段,其核心是对每个事务都采用先尝试后提交的处理方式,因此2PC可看做一个强一致算法。

优缺点

优点:原理简单,实现方便 缺点:同步阻塞,单点问题,脑裂,太过保守

  • 同步阻塞:2PC最明显也是最大的问题,极大的限制分布式系统的性能,提交过程中参与该事务的逻辑都处于阻塞状态。
  • 单点问题:如果参与者出现问题,协调者可以通过超时机制避免一直阻塞,但是如果如果协调者出现问题,那么整个二阶段都无法运转,更为严重的是如果在阶段二出现问题,在新的协调者选出之前,因为所有参与者都在等待协调者的恢复,那么其他参与者都会一直处于事务锁定状态,无法继续执行其他操作。
  • 数据不一致:如果二阶段出现网络分区,导致只有部分参与者收到Commit消息,那么就会出现数据数据不一致
  • 太过保守:2PC没有完善的容错机制,如果参与者出错无法返回响应,协调者只能依靠超时机制来判断是否要中断事务,较为保守。

3PC

三阶段提交,针对2PC的缺点进行相应改进。3PC分为CanCommit, PreCommit和do Commit三个阶段。

新增CanCommit阶段在事务开始之前对所有的参与者做一次健康度检测,这样如果有参与者处于宕机状态,就可以快速中断事务,而不是直接进入准备阶段,避免正常的机器执行一次可以预见的预提交和回滚。浪费性能。

另外在PreCommit阶段解决了引入了参与者的超时机制,2PC仅在协调方有超时机制,3PC在参与者也引入了超时机制,在超时未接到协调者反馈的情况下,根据所处阶段进行处理,避免无限阻塞。

执行过程

阶段一:CanCommit

  1. 事务询问:协调者向所有的参与者发送包含事务内容的CanCommit请求,询问是否可以执行事务提交操作,并开始等待个参与者的响应
  2. 各参与者向协调者反馈事务询问的响应:参与者接到CanCommit请求后,如果认为自己能顺利执行事务,就反馈给协调者Yes响应,并进入预备状态。否则反馈给协调者No响应

阶段二:PreCommit

协调者根据响应决定是否进行PreCommit操作,同样包含两种可能: 执行事务预提交:所有参与者都反馈YES

  1. 发送预提交请求:协调者向所有参与者阶段发送PreCommit请求,并进入PrePared阶段。
  2. 事务预提交:参与者接到PreCommit请求后,执行事务,并将Undo和Redo信息记入事务日志。
  3. 反馈事务提交结果:参与者向协调者ACK消息,等待最终消息

中断事务:任一参与者反馈NO

  1. 发送中断请求:协调者向参与者节点发出abort消息
  2. 事务中断:无论是收到参与者的abort请求,还是等待协调者消息过程中超时,参与者都中断事务。

阶段三:Do Commit

同样有两种可能;

执行提交

  1. 发送提交请求。协调者接到所有的ACK消息,自身从“预提交”状态转换到“提交”状态,并向参与者发送doCommit请求
  2. 事务提交:参与者接到消息后正式提交事务
  3. 反馈事务提交结果:参与者完成事务提交后,向协调者发送Ack消息
  4. 完成事务:协调者接收到所有ACK消息后,完成事务

中断事务:任一参与者返回NO,或者超时未响应

  1. 发送中断请求
  2. 事务回滚,参与者利用二阶段的Undo信息执行事务回滚
  3. 反馈事务回滚结果
  4. 中断事务

优缺点

相较于2PC最大的优点是降低参与者阻塞范围,并且通过PreCommit阶段解决了出现单点故障后的无限阻塞问题。 缺点:引用新的问题,参与者接到PreCommit消息后,如果出现网络分区,此时协调者和参与者无法通行,参与者依然会进行事务提交,导致数据不一致。

Paxos算法

Paxos引用了过半的概念,也就是少数服从多数的原则。是目前公认的解决分布式一致性问题最有效的算法之一。 具体的推到合验证过程暂时不做深究,这里直接说Paxos算法的运转方式。Paxos中定义了三种角色:Proposer,Acceptor,Learner。一个节点可以担任多个角色。所有Acceptor会组成多个集合,每个集合都需要包含半数以上的Acceptor,显而易见的任意两个集合之间必定包含至少一个公共Acceptor,也就不存在两个多数集合之间信息阻断的问题了。

选定提案

选定提案的过程分为两个阶段: 阶段一:

  1. Proposer选择一个新的提案编号Mn(这个编号可产生重复的),然后向某个Acceptor集合的成员发送请求。我们将该请求称为编号为Mn提案的Prepare请求。
  2. 如果一个Acceptor收到这个编号为Mn的Prepare请求,且编号Mn大于该Acceptor已经响应的所有Prepare请求的编号,那么Acceptor就将他已经批准过的最大编号的提案作为响应反馈给Proposer,这个返回的旧最大编号称为Vn, 同时该Acceptor保证不再批准任何编号小于Mn的提案。

阶段二:

  1. 如果Proposer收到来自半数的Acceptor对于其发出的编号为Mn的Prepare请求的响应,那么他就会发送一个针对[Mn,Vn]提案的请求给Acceptor。这个请求称为Accept请求。Vn就是刚才收到的响应中编号最大的提案的值。当然如果半数以上的Acceptor都没有批准过任何提案,即响应中不包含任何提案,那么此时Vn值就可以由Proposer任意设置。Vn用来保证节点出现故障时或重启时的恢复。
  2. 如果Acceptor收到这个针对[Mn,Vn]提案的Accept请求,只要该Acceptor尚未对编号大于Mn的Prepare请求做出响应,它就可以通过提案。

避免死循环

以上提案过程,有个缺点,如果Proposer1提交M1的请求,并完成了阶段一,但是此时Proposer2提交了M2的请求,那么Proposer1在阶段二提交的M1的Accept请求就会被忽略,然后Proposer1提交M3的请求,导致Proposer2的M2Accept请求也被忽略,进而Proposer2会提交M4请求,这就造成了死循环 。因此为了避免这种情况,就必须选一个主Proposer且规定只有主Proposer才能提出提案。这样就有效的避免了死循环的发生。如果主Proposer故障和网络分区,那么就换一个主Proposer,比较这个主Proposer只承担一个发送者的角色,也没有所谓的数据一致性的问题。

获取提案

通过上面的过程,一个提案就已经被选定了,接下来Learner就可以获取提案。Learner同样是一个集合。Acceptor选定提案后,就让其发给特定的Learner集合,该集合的任一个Learner在接到一个提案被选定的消息后通知其他Learner,这个一个最终一致的过程。为什么不让Acceptor通知所有Learner呢?虽然这种做法能让所有Learner尽快获取被选定的提案,但是通信次数则会大大增加,如果有X个Acceptor,Y个Learner,那么就需要X*Y次通信。那为什么不选择一个主Learner接收提案呢,再由主Learner通知其他Learner,这样不就只有X+Y次通信了吗?答案是这样就出现了单节点的场景,容灾性差。因此最终方案就是节点平等,都是主Learner,即提升了容灾性,又保证通信次数只有X+Y。

小结

2PC,3PC与Paxos都从不同方面不同程度的解决了分布式的数据一致性问题。2PC实现简单,保证了分布式事务的原子性,但是依然存在诸如同步阻塞,无限等待和脑裂的问题。3PC通过在2PC的基础上新增PreCommit,避免了2PC的无限等待问题。Poxos则引用半数的概念,且各个节点角色可以轮换,避免了分布式单点的出现,因此Paxos算法即解决了无限等待的问题,也解决了脑裂的问题,是目前最优秀的分布式一致性协议之一。


开发成长之旅 [持续更新中...]
欢迎关注…