【分布式理论11】分布式协同之分布式事务

文章目录

    • [一. 什么是分布式事务?](#一. 什么是分布式事务?)
    • [二. 分布式事务的挑战](#二. 分布式事务的挑战)
    • [三. 事务的ACID特性](#三. 事务的ACID特性)
    • [四. CAP理论与BASE理论](#四. CAP理论与BASE理论)
      • [1. CAP理论](#1. CAP理论)
        • [1.1. 三大特性](#1.1. 三大特性)
        • [1.2. 三者不能兼得](#1.2. 三者不能兼得)
      • [2. BASE理论](#2. BASE理论)
    • [五. 分布式事务解决方案](#五. 分布式事务解决方案)
      • [1. 两阶段提交(2PC)](#1. 两阶段提交(2PC))
      • [2. TCC(Try-Confirm-Cancel)](#2. TCC(Try-Confirm-Cancel))
    • [六. 小结](#六. 小结)

之前我们了解分布式系统中的互斥问题及其解决方案(分布式锁)。互斥问题讨论的是多个进程对同一个临界资源进行操作的问题,而本文将要讨论的是同一个进程对多个临界资源进行操作的问题。

一. 什么是分布式事务?

简单来说,分布式事务就是跨多个独立的资源(比如数据库)进行的事务。

举个例子,假设一个银行系统需要处理一次转账操作:从A账户转出100元分别到B账户30元、C账户70元。这种操作不仅仅涉及到一个数据库,而是涉及多个资源(A账户、B账户、C账户)。这个转账操作要么完全成功,所有的账户变动都要完成;要么完全失败,没有任何账户被修改。类似这样的跨多个资源的事务,我们称之为分布式事务。

二. 分布式事务的挑战

在分布式系统中,跨多个服务和数据库执行的事务面临以下几个挑战:

  • 一致性问题:如何保证数据在多个系统中保持一致?
  • 网络故障:网络不稳定可能导致事务执行失败,如何保证事务不会中途丢失或被错误提交?
  • 并发冲突:多个服务之间并发执行的事务如何互不干扰?

为了处理这些挑战,分布式事务采用了不同的理论和技术框架来确保数据一致性、可用性和事务的正确性。

三. 事务的ACID特性

分布式事务的核心目标是保证事务的一致性和完整性,这与单体应用中的ACID特性密切相关。ACID是事务管理的基本要求,包含以下四个特性:

  • 原子性(Atomicity):事务中的所有操作要么全部成功,要么全部失败,不能部分成功。
  • 一致性(Consistency):事务执行前后的数据一致,系统从一个一致性状态转变到另一个一致性状态。比如:从 A 账户转出 100元,B 账户中到账 30 元,C 账户中到账 70 元。完成这个事务操作以后,A 账户减少的钱数与 B、C 账户增加的钱数总和应该是一样的,都是 100 元。
  • 隔离性(Isolation):并发执行的事务互不干扰,每个事务对外界是隔离的。
  • 持久性(Durability):一旦事务提交,数据更改就会永久保存,即使系统崩溃也不丢失。

在单体架构中,ACID特性易于实现,但在分布式系统中,由于网络延迟、节点故障等问题,保证强一致性变得困难。此时,我们需要更灵活的解决方案。

四. CAP理论与BASE理论

1. CAP理论

1.1. 三大特性

在分布式系统中,由于网络和硬件的限制,无法同时保证一致性可用性分区容错性 ,这就是著名的CAP理论的核心思想。CAP理论提出,在一个分布式系统中,最多只能保证以下两个特性:

  • 一致性(Consistency) :所有节点的视图是相同的,保证每个节点的数据在同一时刻一致。

  • 可用性(Availability):可用性是指在分布式系统中,即使一部分节点出现故障,系统仍然可以响应用户的请求。

  • 分区容错性(Partition tolerance):假设两个数据库节点(每个节点数据一致)分布在两个区,而这两个区的通信发生了问题,因此无法达成数据一致,这就是分区问题,此时需要从一致性和可用性之间做出选择。是选择一致性(C),等待两个区的数据同步了再去获取数据,还是选择可用性(A),只获取其中一个区的数据?
1.2. 三者不能兼得

CAP理论表明,当网络分区发生时,分布式系统必须在一致性和可用性之间做出选择。如下例子:

业务代码对两个节点的通信失败,往数据库 01 写入记录 A 时,需要锁住数据库02 中的记录 A,不让其他业务代码修改此纪录,直到数据库 01 修改完成。一致性和可用性在此刻是矛盾的,不能兼得。

保证特性 放弃特性 适用场景 说明
一致性、可用性 分区容错性 不适用(无法实现) 如果放弃分区容错性,就等于放弃使用分布式系统,即单体。
一致性、分区容错性 可用性 金融领域(如银行、支付系统等) 需要保证数据一致性,甚至在网络分区时也要牺牲系统可用性,保证交易数据的正确性和一致性。
可用性、分区容错性 一致性 ToC端应用(如电商网站、社交平台等) 强调用户体验,牺牲部分一致性以换取系统高可用性,允许数据暂时不一致。适合大流量和高并发的应用场景。

2. BASE理论

由于 CAP 理论导致一个应用同时至多只能支持两个特性,无法三全其美,且高并发系统追求的往往是可用性,因此对 CAP 理论进行进一步扩充,产生了 BASE 理论。

特性 说明 举例
基本可用性 系统能够在流量激增或节点故障时,通过限流或降级保证用户请求可用。 电商系统在流量激增时,优先保证核心业务(如订单处理),将非核心业务降级处理。
软状态 数据副本之间允许存在短时间的数据不一致,容忍数据同步延迟。 数据库01中记录A写入后,数据库02中的记录B会在一定延迟后同步,而不是立即同步。
最终一致性 数据在短时间内可能不一致,但过了一段时间后,数据会最终达到一致。 在分布式系统中,数据副本可能会在网络延迟时出现不一致,但经过一段时间,数据会同步一致。

BASE理论强调的是最终一致性 ,而不是传统数据库中的强一致性。它适用于那些需要高可用性和容忍短期不一致的系统,例如电商平台和社交网络

五. 分布式事务解决方案

为了在分布式系统中保证事务的正确性,业界提出了多种分布式事务解决方案,常见的有两阶段提交(2PC)TCC(Try、Confirm、Cancel)

1. 两阶段提交(2PC)

**两阶段提交协议(2PC)的基本思想是通过协调者(Transaction Manager)和参与者(Resource Manager)来控制事务的提交或回滚。2PC的工作过程分为两个阶段:

准备阶段

事务协调者(事务管理器)询问每个参与者是否准备好,马上要执行事务了。事务参与者会根据自身业务和资源情况进行检查,然后给出反馈。

检查过程根据业务内容的不同而不同,例如订票业务需要检查是否有剩余票、扣款业务需要检查余额是否足够。只有检查通过,才能返回就绪(ready)信息。否则,事务将终止,并且等待下次询问。由于检查过程需要完成一些操作,因此需要写 redo 日志和 undo 日志,以便事务失败重试,或者失败回滚时使用。

提交阶段

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

以下是整理后的两种情况的处理过程:

情况 步骤
情况 1:事务回滚 条件:只要有一个事务参与者反馈未就绪(no ready),事务协调者会回滚事务。
1. 事务协调者向所有事务参与者发出回滚请求。
2. 事务参与者使用第一阶段的 undo 日志信息执行回滚操作,并释放事务期间占用的资源。
3. 各事务参与者向事务协调者反馈应答(ack)消息,表示完成回滚操作。
4. 事务协调者接收到所有事务参与者的应答消息,即完成事务回滚。
情况 2:事务提交 条件:当所有事务参与者均反馈就绪(ready)消息时,事务协调者会提交事务。
1. 事务协调者向所有事务参与者发出正式提交事务的请求。
2. 事务参与者执行提交(commit)操作,并释放事务期间占用的资源。
3. 各事务参与者向事务协调者反馈应答(ack)消息,表示完成提交操作。
4. 事务协调者接收到所有事务参与者的应答(ack)消息,即完成事务提交。

尽管2PC简单易理解,但它存在问题,比如在网络分区或故障情况下,可能会导致事务挂起,无法继续提交或回滚,造成数据不一致。

2. TCC(Try-Confirm-Cancel)

TCC(Try-Confirm-Cancel)的核心思想是对于每个资源的原子操作,应用程序都需要注册一个与此操作对应的确认操作和补偿(撤销)操作。其中确认操作负责在原子操作执行成功时进行事务提交,补偿操作负责在原子操作执行失败时对事务进行回滚。

TCC协议分为三个阶段:

  • Try阶段:进行资源的预检查和预留,确保资源可用。
  • Confirm阶段:负责对业务系统做确认提交。如果 Try 阶段执行成功,表明针对资源的操作已经准备就绪,此时执行 Confirm 便会提交对资源的操作。也就是说当资源准备好时,只用提交该操作执行就好了。
  • Cancel阶段 :负责在业务执行错误 ,需要回滚时执行业务取消操作,此时就需要释放 Try 阶段预留的资源了 。换句话说,是在资源操作执行失败的情况下,根据之前预留的资源情况进行回滚

TCC协议通过提供灵活的补偿机制,能够在事务失败时进行回滚,保证系统的一致性。

例子:

假设有一个转账服务,需要把 A 银行中 A 账户的 100 元分别转到 B 银行的 B 账户和 C 银行的 C 账户,这三个银行的转账服务各不相同,因此这次转账服务就形成了一次分布式事务。

阶段 操作描述 具体步骤
Try 阶段 检测资源是否可用,验证所有参与者的资源可用性,并记录相关信息。 1. 检查 A 账户余额是否大于 100 元。 2.记录 A 账户的总金额、转出金额。 3. 记录 B、C 账户的总金额、转入金额。 4. 在数据库中保存相关字段(如余额、转出金额)。 5. 如果资源可用,进入 Confirm 阶段;如果不可用,回滚。
Confirm 阶段 执行具体的转账逻辑,进行资源更新,并设置事务的成功状态。 1. 从 A 账户扣除 100 元,更新余额为 220 - 100 = 120。 2. 更新 B 账户余额为 50 + 30 = 80,C 账户余额为 60 + 70 = 130。 3. 更新交易状态为转账成功。 4. 向所有参与者发出确认提交请求,确认各方操作。
Cancel 阶段 回滚操作,恢复资源到原始状态。 1. 如果 Try 阶段失败或资源无法提供,回滚所有操作。 2. A 账户恢复扣除的 100 元,余额为 120 + 100 = 220。 3. B 账户和 C 账户分别恢复相应的金额,B 账户恢复为 80 - 30 = 50,C 账户恢复为 130 - 70 = 60。 4. 事务回滚并释放占用的资源。

六. 小结

分布式事务的出现带来了很多挑战,但也推动了事务管理理论和实践的不断发展。从ACID特性到CAP理论、BASE理论,再到DTP、2PC和TCC等分布式事务协议,每一种理论和方案都在不同的应用场景中发挥着重要作用。

在实际开发中,选择哪种分布式事务方案应根据业务需求、系统架构、性能要求等因素来决定。对于高一致性要求的金融类系统,2PC可能更合适;而对于电商类高并发系统,TCC和BASE理论的结合则能提供更高的可用性和灵活性。

相关推荐
smileNicky2 小时前
分布式与主流消息中间件总览
分布式
SYKMI2 小时前
关于分布式的误区
分布式
快乐非自愿3 小时前
分布式锁—Redisson的同步器组件
分布式·wpf
桂月二二4 小时前
云原生边缘计算:重塑分布式智能的时空边界
分布式·云原生·边缘计算
格子先生Lab6 小时前
Elasticsearch 入门教学:从零开始掌握分布式搜索引擎
分布式·elasticsearch·搜索引擎
昨天今天明天好多天7 小时前
【Hadoop】
大数据·hadoop·分布式
隔着天花板看星星7 小时前
Flink-DataStreamAPI-执行模式
大数据·分布式·flink
Kale又菜又爱玩7 小时前
Zookeeper实践指南
java·分布式·zookeeper
江湖十年8 小时前
如何基于 Go 语言设计一个简洁优雅的分布式任务系统
分布式·后端·go
WeiLai111210 小时前
面试基础--Redis 缓存穿透、缓存击穿、缓存雪崩深度解析
java·redis·分布式·后端·缓存·面试·架构