分布式基础之二阶段提交

二阶段提交(Two Phase Commit)在分布式事务处理中非常常见。它主要用来保证分布式事务处理的一致性,决定事务的提交或回滚。目前二阶段提交广泛应用于关系型数据库的分布式事务处理中,它是分布式系统中的一个常见协议。

需求

为什么要二阶段提交?因为在分布式系统中,每个节点只知道自己的事务是否执行成功了,而分布式系统要求一致性,也就是所有的节点的状态都应该一致。如果某一个事务只在部分节点执行成功,那么势必会导致各分布式节点不一致。二阶段提交就是用来保证要么所有的节点都执行了该事务,要么都不执行。

简介

顾名思义,二阶段提交要通过两个阶段来完成。此外在二阶段中主要分为两种角色:协调节点与普通节点。而且协议中还假设节点不会发生永久性故障,而且任意两个节点都可以互相通信。

提交阶段

在提交阶段,协调节点将事务分发给普通节点,普通节点进行事务的处理并返回响应。具体过程如下:

  1. 协调节点向各普通节点发送事务内容,等待普通节点的回应

  2. 各普通节点执行事务,并记录下日志(用来事务中断时进行回滚)

  3. 各普通节点返回响应,判断事务是否执行成功

注:协调节点需要设置超时时限,如果有普通节点在超时时限内都没有响应,认为事务执行失败。

执行阶段

在执行阶段,根据各普通节点的响应结果来进行事务的提交或回滚。

执行事务

  1. 所有的普通节点都返回说事务执行成功

  2. 协调者向所有的普通节点发送执行命令

  3. 普通节点在收到执行命令后对事务结果进行提交,并释放整个事务执行期间占用的资源

  4. 提交完成后向协调节点发送回应消息(ack)

  5. 协调节点接收到所有的回应消息后完成事务处理

中断事务

  1. 有普通节点执行事务失败或者超时

  2. 协调者向所有普通节点发送回滚请求

  3. 普通节点根据日志执行回滚操作,并释放在整个事务执行期间占用的资源

  4. 回滚完成后向协调节点发送回应消息(ack)

  5. 协调节点接收到所有的回应消息后完成事务中断

下面是事务提交成功的说明图:

二阶段事务成功

下面是事务中断的说明图:

二阶段事务中断

注:图片来源于网络

节点运行状况

我们来分类讨论一下各节点出现问题时会对二阶段提交产生什么影响:

协调节点正常,普通节点失效

如果普通节点在提交阶段失效会导致因超时而中断事务;如果在执行阶段失效,那么会导致这个节点与其他的节点出现不一致现象。这时可以通过协调者对该节点进行事务的重新提交,或者该节点主动询问协调者或其他节点进行同步。

协调节点失效,普通节点正常

如果调节节点失效,那么会导致收到提交请求的普通节点占用了事务资源,并一直在等待调节节点作出反馈来决定是执行事务还是回滚。可以等待协调节点恢复或者设定一种备用协调节点机制。

协调节点失效,普通节点失效

在这种情况下会出现一种非常危险的错误,如果协调节点在发出了部分执行命令后失效,且接收到该执行命令的节点后来也失效了,那么就无法知道整个分布式系统的最终决定要不要执行该事务操作。这时只能进行数据订正或者等节点恢复正常后再进行相关操作。

优缺点

优点

二阶段明显的优点就是逻辑很简单,易于在系统中实现。

缺点

就是因为二阶段提交协议的简单,也使得它存在一些缺陷:

单点问题:

显然协调节点在整个协议中处在一个中心位置,一旦协调节点出现问题,那么整个二阶段操作都会受到严重影响。

数据不一致:

也就是协调节点失效,普通节点失效的情况,这时候可能部分普通节点执行了事务,而部分普通节点没有执行事务。

阻塞引起的性能问题:

由于在二阶段提交中需要等到所有的节点都作出反应,需要花费大量的开销在阻塞操作上,此时普通节点不能进行其他事物操作,性能会受到影响。

文章导航