什么是两阶段提交和三阶段提交?


一、背景

在分布式系统中,不同节点通过网络进行通信和协调,并且在物理上是相互独立的,所以为了保证数据一致性,我们需要引入分布式事务。(具体可查看《什么是分布式事务?》

而分布式事务中比较经典的一致性算法有二阶段提交三阶段提交

二、两阶段提交和三阶段提交的流程是怎样的?

两阶段提交(2PC)三阶段提交(3PC)主要是引入了一个协调者(Coordinator)组件,负责调度所有分布式节点的执行,并让当前节点了解其他节点的任务执行状态。通过通知和表决的方式,协调者会决定是执行提交(Commit)操作还是回滚(Rollback)操作。这样就可以确保在分布式系统中所有节点达到一致的状态。

1、两阶段提交(2PC)

两阶段提交要注意的点:

  • 在分布式系统中,存在一个节点作为协调者(Coordinator),其他节点作为参与者(Participants),并且节点之间可以通过网络通信
  • 节点具有故障恢复能力
  • 通过预写式日志存储即将执行的操作,防止节点发生故障而丢数据

两阶段提交包含两个阶段,分别是:

  • Commit-request(提交请求)阶段
    1. (协调者)询问各个参与者是否可以正常执行
    2. (参与者)执行事务,但不提交
    3. (参与者)反馈自己的决策,包括同意和取消
  • Commit(提交)阶段
    1. (协调者)向所有参与者发起事务提交通知
    2. (参与者)收到通知,提交事务,释放资源
    3. (参与者)反馈事务提交结果

两阶段提交

但是呢,两阶段提交会存在下面问题:

  • 资源同步阻塞:如果参与者占有了某些公共资源,那么其他请求该资源的节点将被阻塞,影响系统性能
  • 单点故障:如果协调者发生故障,那么参与者将会一直阻塞,无法继续执行其他操作,导致系统可用性降低
  • 数据不一致:如果协调者发送Commit提交通知时,由于网络原因只有部分参与者收到并执行Commit,其余的参与者没收到通知所以一直在阻塞,那么这段时间就会出现数据不一致

2、三阶段提交(3PC)

三阶段提交的出现是为了解决二阶段提交中出现的同步阻塞和单点故障问题,通过引入超时机制和拆分第一阶段,提供了更好的可靠性和数据一致性。

三阶段提交包含三个阶段,分别是:

  • CanCommit(询问是否可提交)
    1. (协调者)询问各个参与者是否可以正常执行
    2. (参与者)判断自己是否可以执行,不做事务操作
    3. (参与者)反馈自己的决策,包括可以和不可以
  • PreCommit(准备提交)
    1. (协调者)询问各个参与者是否可以正常执行
    2. (参与者)执行事务,但不提交
    3. (参与者)反馈自己的决策,包括同意和取消
  • DoCommit(执行提交)
    1. (协调者)向所有参与者发起事务提交通知
    2. (参与者)收到通知,提交事务,释放资源(三阶段提交中超时也会自动提交
    3. (参与者)反馈事务提交结果

三阶段提交

三阶段提交相比二阶段提交做出了以下优化:

  • 二阶段提交中,只有协调者有超时机制,如果一定时间内没收到参与者的反馈,则认为失败,但是还是会存在同步阻塞和单点故障的问题
  • 三阶段提交中,除了协调者有超时机制,参与者也有,如果在DoCommit阶段时没有收到协调者的提交通知,在一定时间后就会超时自动提交
  • 三阶段提交中,新增一个PreCommit缓冲阶段,以确保在最终提交之前各节点的状态是一致的

但是呢,三阶段提交会存在下面问题:

  • 在DoCommit阶段中,如果参与者由于网络故障等原因无法收到协调者的消息(如提交、回滚),那么参与者会进行超时自动提交,可能会导致数据不一致性(如协调者发送abort通知,但某个参与者由于网络原因没收到而超时自动提交了,会导致数据跟其他正常收到abort通知的参与者不一致)

文章作者: GaryLee
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 GaryLee !
  目录