分布式协同 - 分布式事务_2PC & 3PC解决方案

文章目录

  • 导图
  • Pre
  • [2PC(Two-Phase Commit)协议](#2PC(Two-Phase Commit)协议)
    • 准备阶段
    • 提交阶段
      • [情况 1:只要有一个事务参与者反馈未就绪(no ready),事务协调者就会回滚事务](#情况 1:只要有一个事务参与者反馈未就绪(no ready),事务协调者就会回滚事务)
      • [情况 2:当所有事务参与者均反馈就绪(ready)消息时,事务协调者会提交(commit)事务](#情况 2:当所有事务参与者均反馈就绪(ready)消息时,事务协调者会提交(commit)事务)
  • [3PC(Three-Phase Commit)协议](#3PC(Three-Phase Commit)协议)
  • [3PC 和 2PC 的主要区别](#3PC 和 2PC 的主要区别)
    • [1. 阶段数量不同](#1. 阶段数量不同)
    • [2. 容错能力](#2. 容错能力)
    • [3. 协议的安全性与复杂性](#3. 协议的安全性与复杂性)
    • [4. 阻塞问题](#4. 阻塞问题)
    • [5. 事务资源锁定](#5. 事务资源锁定)
    • [6. 性能开销](#6. 性能开销)
  • 总结

导图


Pre

分布式协同 - 分布式事务一二事儿DTP 定义了分布式事务的处理模型,可以针对这个模型提出分布式事务的解决方案,2PC 就是其中一种。

2PC 的全称为两阶段提交(Two Phase Commitment Protocol),是 DTP 模型的最佳实践,解决了在分布式服务或数据库场景下,同一事务对多个节点进行操作的数据一致性问题。

2PC 在一定程度上遵守 ACID 理论的刚性事务的要求,保证了强一致性。 2PC 中有两个概念,

  • 一个是事务协调者,对应 DTP 模型中的事务管理器,用来协调事务,所有事务什么时候准备好、什么时候可以提交都由它来协调和管理;
  • 另一个是事务参与者,对应 DTP 模型中的资源管理器,主要负责处理具体事务、管理需要处理的资源。例如事务参与者可以处理订票业务,扣款业务。

2PC(Two-Phase Commit)协议

java 复制代码
+-----------------+                +------------------+                +-----------------+
|   Transaction   |                |   Coordinator    |                |   Participant   |
|     Client      |                |       Node       |                |       Node      |
+-----------------+                +------------------+                +-----------------+
        |                                  |                                   |
        |----------(1) Request Start ------>                                   |
        |                                  |                                   |
        |                                  | --------------(2) Prepare-------->|
        |                                  |                                   |
        |                                  | <--------- (3) Acknowledge ------|
        |                                  |                                   |
        |                                  |                                   |
        |                                  | --------------(4) Commit--------->|
        |                                  |                                   |
        |                                  | <--------- (5) Acknowledge ------|
        |                                  |                                   |
        |                                  |                                   |
        |                                (End)                               (End)

准备阶段

第一阶段(准备阶段):如下图 所示

事务协调者(事务管理器)给每个事务参与者(资源管理器)发送准备(prepare)消息,目的是询问大家是不是都准备好了,马上就要执行事务了。事务参与者会根据自身业务和资源情况进行检查,然后给出反馈。检查过程根据业务内容的不同而不同,例如订票业务需要检查是否有剩余票、扣款业务需要检查余额是否足够。

只有检查通过,才能返回就绪(ready)信息。否则,事务将终止,并且等待下次询问。由于检查过程需要完成一些操作,因此需要写 redo 日志和 undo 日志,以便事务失败重试,或者失败回滚时使用。


提交阶段

第二阶段(提交阶段):如下图所示

如果事务协调者接收到事务参与者检查失败或者超时的消息,会给其发送回滚(rollback)消息,否则发送提交(commit)消息。

情况 1:只要有一个事务参与者反馈未就绪(no ready),事务协调者就会回滚事务

  • a) 事务协调者向所有事务参与者发出回滚请求。
  • b) 事务参与者使用第一阶段中 undo 日志里的信息执行回滚操作,并且释放整个事务期间占用的资源。
  • c) 各事务参与者向事务协调者反馈应答(ack)消息,表示完成操作。
  • d) 事务协调者接收到所有事务参与者反馈的应答消息,即完成了事务回滚。

情况 2:当所有事务参与者均反馈就绪(ready)消息时,事务协调者会提交(commit)事务

  • a) 事务协调者向所有事务参与者发出正式提交事务的请求。
  • b) 事务参与者执行提交(commit)操作,并释放整个事务期间占用的资源。
  • c) 各事务参与者向事务协调者反馈应答(ack)消息,表示完成操作。
  • d) 事务协调者接收到所有事务参与者反馈的应答(ack)消息,即完成了事务提交。

3PC(Three-Phase Commit)协议

3PC(三阶段提交)是分布式事务中的一种协议,旨在解决2PC协议中的阻塞问题。3PC协议通过在2PC的基础上增加了一个阶段,增加了事务的容错能力,从而避免了协调者或参与者崩溃时可能发生的阻塞现象。

3PC的三个阶段

  1. CanCommit 阶段(询问阶段)

    • 协调者向所有参与者发送"CanCommit"请求,询问它们是否可以提交事务。
    • 参与者收到请求后,会检查本地的事务状态。如果没有冲突,且可以提交,它们就返回"Ready"响应;如果事务存在问题,则返回"No"响应,表示无法提交。
  2. PreCommit 阶段(预提交阶段)

    • 如果所有参与者都返回了"Ready",协调者就会向所有参与者发送"PreCommit"命令,表示准备提交事务,并让它们锁定相关资源。
    • 参与者在接收到"PreCommit"命令后,执行事务的预提交操作并返回确认。
  3. DoCommit 阶段(提交阶段)

    • 如果所有参与者都返回了预提交确认("PreCommit"),协调者会向所有参与者发送"DoCommit"命令,正式提交事务。
    • 参与者接收到"DoCommit"命令后,执行提交操作,事务完成。

3PC 的流程

java 复制代码
+-----------------+                +------------------+                +-----------------+
|   Transaction   |                |   Coordinator    |                |   Participant   |
|     Client      |                |       Node       |                |       Node      |
+-----------------+                +------------------+                +-----------------+
        |                                  |                                   |
        |----------(1) Request Start ------>                                   |
        |                                  |                                   |
        |                                  |  --------(2) CanCommit --------->|
        |                                  |                                   |
        |                                  | <----------(3) Ready/No --------|
        |                                  |                                   |
        |                                  |  --------(4) PreCommit --------->|
        |                                  |                                   |
        |                                  | <----------(5) PreCommitAck -----|
        |                                  |                                   |
        |                                  |  --------(6) DoCommit ---------->|
        |                                  |                                   |
        |                                  | <----------(7) DoCommitAck ------|
        |                                  |                                   |
        |                                (End)                               (End)

3PC 和 2PC 的主要区别

1. 阶段数量不同

  • 2PC 有两个阶段:

    1. Prepare: 协调者询问参与者是否能提交事务。
    2. Commit/Abort: 根据参与者的响应,协调者决定是否提交或回滚事务。
  • 3PC 有三个阶段:

    1. CanCommit: 协调者询问参与者是否准备提交。
    2. PreCommit: 协调者发送预提交命令,参与者准备提交并锁定资源。
    3. DoCommit: 协调者发送最终提交命令,事务正式提交。

2. 容错能力

  • 2PC 在协调者或参与者崩溃时可能会出现阻塞。例如,如果协调者崩溃后,参与者不知道是应该提交还是回滚,系统可能会陷入阻塞状态,无法继续执行。
  • 3PC 增加了一个额外的阶段(PreCommit),并且在每个阶段都有明确的响应协议,可以减少系统在协调者或参与者崩溃时的阻塞风险。3PC通过引入超时机制预提交锁定,有效减少了数据不一致和系统停滞的概率。

3. 协议的安全性与复杂性

  • 2PC 协议相对简单,但存在阻塞问题,且在部分情况下(例如,协调者崩溃),事务无法保证最终一致性。
  • 3PC 协议在设计上更加复杂,通过引入预提交阶段,提高了系统的容错能力,但也增加了协议的开销和实现的复杂性。

4. 阻塞问题

  • 2PC 存在阻塞问题,特别是在协调者或参与者崩溃的情况下,事务无法继续或回滚,可能会导致长时间的停滞。
  • 3PC 通过引入额外的阶段,并要求所有参与者在每个阶段都给予明确的响应,避免了阻塞的可能性。当协调者或参与者崩溃时,系统会通过超时机制自动恢复,减少了长时间的停滞。

5. 事务资源锁定

  • 2PC 中,事务资源在提交后才被释放,可能会因为参与者的延迟或崩溃导致长时间的资源占用。
  • 3PC 引入了预提交阶段,在PreCommit时就锁定了资源并确保它们在提交前是有效的,因此能更有效地管理资源的占用。

6. 性能开销

  • 2PC 因为只有两个阶段,协议简单,性能相对较好,但当系统出现故障时,性能和一致性会受到较大影响。
  • 3PC 虽然增加了一个阶段,但引入了更多的容错机制,可能会有稍微的性能开销,但能在故障恢复时保持更高的可用性。

总结

特性 2PC (Two-Phase Commit) 3PC (Three-Phase Commit)
阶段数量 2个阶段:Prepare(准备阶段)和Commit/Abort(提交/回滚阶段) 3个阶段:CanCommit(询问阶段)、PreCommit(预提交阶段)、DoCommit(提交阶段)
协议设计 基于两阶段协议,协议简单但容易导致阻塞问题 基于三阶段协议,增加了预提交阶段,减少了阻塞问题
阻塞问题 存在阻塞问题,特别是当协调者或参与者崩溃时,系统可能无法继续 通过引入PreCommit阶段,减少了崩溃时的阻塞问题,避免了长时间停滞
协调者崩溃的处理 协调者崩溃后,参与者不确定事务是提交还是回滚,导致阻塞 由于引入了CanCommit和PreCommit阶段,协调者崩溃后的恢复能力较强,减少了阻塞的可能
参与者崩溃的处理 如果参与者在Prepare阶段崩溃,事务可能无法提交 在PreCommit阶段,参与者能锁定资源,如果崩溃,系统能更好恢复,减少了不一致情况
事务提交的一致性 保证一致性,但有可能因为协调者或参与者崩溃导致无法提交或回滚 在多数情况下保证一致性,并且通过额外阶段减少了崩溃带来的影响
资源管理 资源管理依赖于Prepare阶段,协调者发出提交或回滚命令 资源管理通过PreCommit阶段锁定资源,协调者发送最终提交命令
性能开销 由于只有两个阶段,性能较高,但可能因为故障导致较长的延迟 增加了一个阶段,性能会有一定的开销,但能有效减少阻塞问题
协议复杂性 协议较简单,实现起来相对容易,但缺乏容错能力 协议更复杂,要求在协议层面上有更多的容错设计和实现
适用场景 适用于对一致性要求较高的场景,如分布式数据库事务 适用于对高可用性和容错性要求较高的场景,尤其是需要更好恢复能力的分布式系统
超时处理 通常需要外部机制(如超时检测)来处理超时问题 协议本身提供了对超时和崩溃的处理机制,有更强的容错能力
  • 2PC 由于其简单的设计,适用于一些不涉及复杂容错的场景,但它容易因为崩溃或故障导致阻塞问题,事务可能无法继续进行。
  • 3PC 在 2PC 的基础上增加了一个阶段,提升了系统容错能力,减少了由于协调者或参与者崩溃导致的阻塞,但相应地增加了协议的复杂度和性能开销。

在选择2PC还是3PC时,需要根据具体应用场景的容错要求、性能需求以及系统复杂度进行权衡。

相关推荐
躺不平的理查德3 小时前
General Spark Operations(Spark 基础操作)
大数据·分布式·spark
talle20213 小时前
Zeppelin在spark环境导出dataframe
大数据·分布式·spark
渣渣盟3 小时前
大数据开发环境的安装,配置(Hadoop)
大数据·hadoop·分布式
Angindem4 小时前
SpringClound 微服务分布式Nacos学习笔记
分布式·学习·微服务
龙仔72512 小时前
离线安装rabbitmq全流程
分布式·rabbitmq·ruby
〆、风神14 小时前
Spring Boot 整合 Lock4j + Redisson 实现分布式锁实战
spring boot·分布式·后端
胡萝卜糊了Ohh15 小时前
kafka
分布式·kafka
桑榆080618 小时前
Spark-Streaming核心编程
大数据·分布式·spark
nbsaas-boot19 小时前
分布式微服务架构,数据库连接池设计策略
分布式·微服务·架构