经典一致性协议总结

上篇上述了分布式系统的一些经典理论,即在设计分布式系统时候应该考虑的问题,那么本篇主要讲述分布式系统中数据的一致性,即数据在不同节点中如何保证一致性的问题。

经典一致性协议,主要分为以下三个:

  • 二阶段提交协议——2PC
  • 三阶段提交协议——3PC
  • paxos算法

下面就这三个协议做具体的分析与总结。

1、二阶段提交协议——2PC

分布式系统中同样有数据库中的事务的概念,当不同的节点处理一个事物操作额时候,虽然本节点知道当前事务操作的成功与否,但是却不知道其它节点是否成功失败,如何同一个事务操作在本节点上成功,但是在其它节点上失败了,那么肯定会造成所谓的不一致现象。

二阶段提交协议提出就是解决在分布式事务操作上的一致性问题

2PC主要分为两个阶段:提交事务阶段、执行事务阶段
分为两个角色:协调者和参与者

第一阶段:提交事务阶段

1.事务询问:协调者向所有参与者发送事务内容,询问是否可以执行事务提交操作,并开始等待参与者的响应。
2.执行事务:各参与者节点执行事务操作,将类似undo和redo的信息持久化到日志中,注意,这里进行了实际的事务操作过程
3.反馈事务:参与者成功执行了事务操作,则返回成功给协调者,否则则反馈失败给协调者,无论是成功还是失败都需要反馈。

第二阶段:执行事务的提交

第二阶段协调者将根据第一阶段的反馈结果,决定事务最终是否提交或者中断。
执行事务提交:第一阶段所有参与者都回复成功

1.协调者向所有参与者发送提交事务commit请求
2.参与者收到commit请求后,会正式提交事务操作,并完成之后释放对应占用资源
3.反馈事务提交结果:提交成功后,返回ack确认信息
4.完成事务:协调者接受到所有参与者发送的ack消息后,完成事务。

中断事务:其中任何一个参与者向协调者反馈了失败消息,或者协调者等待超时了还无任何反馈消息,此时会执行中断事务请求。

1.发送回滚请求:协调者会向所有的参与者发送Rollback请求
2.事务回滚:参与者接收到了回滚请求后,会利用第一阶级持久化到入职的undo信息,执行回滚操作,回滚操作完成之后会释放对应占用的资源
3.反馈回滚结果:参与者完成回滚之后,会向协调者发送ack确认信息。
4.协调者受到左右信息之后,完成事务的回滚中断。

事务提交和事务回滚两种操作的示意图如下:
在这里插入图片描述

两段式提交2PC的优缺点
优点:

原理简单,实现方便

缺点:

1.同步阻塞
由于在协调者还未发送提交或者中断请求时,所有参与者都处于阻塞状态,因为每个参与者反馈信息的延时是不一致的,因此存在短板效应,同步阻塞。

2.单点问题
很明显,协调者自身是2PC里面最重要的角色,其本身存在单点问题,一旦故障,无法继续完成事务操作。

3.数据不一致
在2PC的第二阶段,执行事务提交时,如果发生了网络问题,导致只有部分参与者收到了提交请求,此时这部分的参与者会提交事务,没有收到的参与者则会继续等待事务是否提交,此时整个系统则会出现不一致。

4.太过保守
没有容错机制,一旦任何一个参与者或者网络出现问题,都会导致整个事务的失败,重试。这样的效率太低下的了。

2.三段式提交协议——3PC

由于二段式提交协议存在诸如同步阻塞、脑裂、单点故障等问题,三段式提交协议随之产生,在2PC的基础上。

协议说明
三段式提交议其核心思想,是将2PC中第一阶段(提交事务请求)一分为二,形成三个步骤,分别为CanCommit,PreCommit和do Commit. 三个步骤的具体说明如下:

阶段一:CanCommit

1.事务询问
协调者向所有参与者在发送一个包含事务内容的CanCommit请求,询问是否可以执行事务提交操作,并等待各个参与者的回答。
2.反馈询问
参与者在接收到协调者发送的CanCommit请求后,如果可以执行则反馈成功,如果不能执行则反馈失败。
注意:对于所有的参与者,在阶段一上并没有做实际的事务操作,只是根据自身的节点状态提前做一个判断。

阶段二:PreCommit
在阶段二中,协调者根据参与者的反馈请求,决定是否可以进行事务的PreCommit操作,则分为两种情况。
执行事务的预提交:当所有参与者都回复成功

1.发送预提交请求
协调者向所有参与者节点发送PreCommit请求,进入prepare阶段
2.事务预提交
参与者接收到PreCommit请求,执行事务操作将类似undo和redo的信息持久化到日志中,注意,这里进行了实际的事务操作过程
3.反馈响应
参与者成功执行则反馈ack信息,同时等待最终的提交请求

中断事务:当阶段一中有任意参与者回复失败

1.发送中断
协调者向所有参与者节点发送中断abort请求
2.中断事务
无论是收到协调者的中断请求,还是等待协调者请求超时的情况,参与者都会中断事务

阶段三:do Commit
在阶段三种进行真正的事务提交,也是会存在两种情况。
**执行提交:**当事务二反馈信息全部成功时

1.发送提交请求
当事务二反馈信息全部成功时,协调者向所有的参与者发送do Commit事务提交请求
2.事务提交
参与者接收到提交请求后,会正式执行事务提交操作,并在提交完成后释放对应资源
3.结果反馈
参与者在完成事务提交之后,想协调者发送反馈ack信息
4.完成事务
协调者接收到所有参与者反馈的ack信息后,完成事务

中断事务:其中任何一个参与者向协调者反馈了失败消息,或者协调者等待超时了还无任何反馈消息,此时会执行中断事务请求。

1.发送回滚请求:协调者会向所有的参与者发送Rollback请求
2.事务回滚:参与者接收到了回滚请求后,会利用第一阶级持久化到入职的undo信息,执行回滚操作,回滚操作完成之后会释放对应占用的资源
3.反馈回滚结果:参与者完成回滚之后,会向协调者发送ack确认信息。
4.协调者受到左右信息之后,完成事务的回滚中断。

值得注意的是,一旦进入阶段三,可能会存在以下两种情况

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

当出现这两种问题时,最终的提交请求会无法到达参与者这里,针对这样的情况3PC统一采取,等待超时之后,继续执行事务提交。

三阶段提交协议流程示意图
在这里插入图片描述

三段式提交协议3PC优缺点

优点:
对于2PC,很明显,将同步阻塞的情况限制在阶段一,这样可以有效降低参与者的阻塞范围,并且能够在单点故障后继续达到一致。

缺点:
由于网络问题,只要参与者接收到了PreCommit,当发生网络分区通信失败请求下,等待超时,3PC协议一定会提交事务,但是往往可能在第二阶段中间发送的是中断事务请求,这样会导致数据的不一致现象。这也是三阶段协议额外引入的一个问题。

参考:

《从paxos到zookeeper》


版权声明:本文为u012414189原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。