1. 2PC

1.1. 简述

二阶段提交(Two-Phase Commit),是一个非常经典的强一致、中心化的原子提交协议。目前,绝大多数关系型数据库都采用二阶段提交协议来完成分布式事务处理(例如mysql的XA协议)。因此二阶段提交协议也被广泛运用到分布式系统中。

顾名思义,算法流程就是分为两个阶段提交某一操作,其分为准备阶段、提交阶段。为了更好描述算法过程,为此定义了两种角色:协调者(Coordinator)、参与者(Participant)。

1.2. 阶段一:准备阶段

准备

准备阶段,又被称为投票阶段(Vote Request),由协调者向参与者发送请求,询问当前事务能否处理成功。参与者则开启本地数据库事务,开始执行数据库操作,但是并不会提交。根据操作结果,返回给协调者“yes/no”,表示事务是否可以提交。

  • 事务询问 协调者向所有参与者发送事务内容,询问是否可以执行事务的提交操作,并等待各参与者的响应
  • 执行事务 各参与者执行事务操作,准备好事务资源,记录undo、redo信息
  • 反馈询问结果 如果参与者成功执行了事务操作,那么返回给协调者yes(表示当前事务可以提交),否者返回给协调者no(表示当前事务不能执行)

1.3. 阶段二:提交阶段

在准备阶段,由于参与者可以返回yes/no,则在提交阶段也会出现两种可能,即全局提交事务、全局回滚事务。

1.3.1. 全局提交事务

全局提交事务

当准备阶段所有参与者都返回yes的响应后,协调者将发起全局提交事务请求。

  • 发送提交请求 由协调者向所有参与者发送global_commit请求,要求提交当前事务
  • 事务提交 当参与者收到global_commit请求后,则执行事务提交操作,并释放整个分布式事务期间占用的事务资源
  • 反馈提交结果 参与在执行完事务提交后,向协调者返回ack消息
  • 完成事务提交 协调者收到所有参与者反馈的ack消息后,给客户端返回结果,完成本次事务

1.3.2. 全局回滚事务

全局回滚事务

当准备阶段有一个参与者都返回no的响应后,或者在协调者等待响应超时后,则协调者将发起全局回滚事务请求,中断事务。

  • 发送回滚请求 由协调者向所有参与者发送global_rollback请求,要求中断当前事务
  • 事务回滚 当参与者收到global_rollback请求后,会利用准备阶段记录的undo信息来进行回滚,并释放整个分布式事务期间占用的事务资源
  • 反馈回滚结果 参与在执行完事务提交后,向协调者返回ack消息
  • 中断事务 协调者收到所有参与者反馈的ack消息后,给客户端返回结果,完成中断事务

1.4. 优缺点

2PC协议明显的优点就是:原理简单、容易实现。但是它的缺点更加明显:

  • 同步阻塞 每个参与者都需要等待其他参与者完成后,才能继续下一阶段,也就是说事务操作逻辑都是处于阻塞状态,极大限制了分布式系统性能
  • 数据不一致 在第二阶段,如果出现网络异常导致一部分参与者收到了commit请求,一部分参与者没有收到commit请求,结果会是一部分参与者提交了事务,一部分参与者无法进行事务提交
  • 单点问题/脑裂 协调者在2PC中,太过重要,当协调者宕机,整个集群将不可用。更可怕的是,协调者在第二阶段之前宕机,那么所有参与者将一直锁定准备阶段的事务资源。脑裂(动态选主情况下)是指因为网络原因,出现多个协调者。
  • 太过保守 任何一个节点故障,都会导致整个事务协调失败,换句话说没有完善的容错机制。

以上摘自: 分布式一致性协议

results matching ""

    No results matching ""