目录
[1、CAP 定理](#1、CAP 定理)
[#1. 运行过程](#1. 运行过程)
[#1.1 准备阶段](#1.1 准备阶段)
[#1.2 提交阶段](#1.2 提交阶段)
[#2. 存在的问题](#2. 存在的问题)
[#2.1 同步阻塞](#2.1 同步阻塞)
[#2.2 单点问题](#2.2 单点问题)
[#2.3 数据不一致](#2.3 数据不一致)
[#2.4 太过保守](#2.4 太过保守)
[Seata的TCC 模式](#Seata的TCC 模式)
需求背景:
- 随着微服务的拆分,服务进行多节点分布式部署,当一个服务节点的业务操作,必须其他几个服务节点的操作成功,才能提交时,就涉及到分布式事务问题;
- 事务就是要不一起成功提交,要不一起失败回滚;
- 当然涉及到分布式事务,其业务操作的链路就会比较长,业务执行的时间就会可能比较长,可能就会长期持有数据库连接,导致连接数占满,导致服务异常,这个就是长事务问题;
- 所以像秒杀等电商高并发场景,为了用户体验好,接口响应快,就不得不做数据的最终一致性处理,做分布式事务维持强一致性可能得不偿失。
- 比如采用缓存进行库存扣减,如果缓存扛不住,可以进行库存分片,分布在多个缓存节点进行扣减,然后利用MQ、延迟队列+任务调度更新趋势库存,满足最终一致,后续可以扫描统计订单数量,来校准库存。
- 比如抽奖场景,用户抽中奖后进行发奖,在写入奖品记录的时候,写入一条中奖奖品和用户信息的 task 消息发送任务,作为补偿使用。当 MQ发送失败的时候,则由任务调度扫描 task 消息进行重新发送,发奖服务进行消费MQ消息进行发奖操作,操作成功后修改task消息表中的状态,也就是利用本地消息表+异步回调来实现最终一致性。
- 当然这里分析调研分布式事务的解决方案,比如两阶段提交2PC、TCC
参考:分布式事务概述与项目实战
本地事务
ACID:数据库事务的几个特性:原子性(Atomicity )、一致性( Consistency )、隔离性或独立性( Isolation)和持久性(Durabilily)
● 原子性:一系列的操作整体不可拆分,要么同时成功,要么同时失败
● 一致性:事务在开始前和结束后,数据库的完整性约束没有被破坏
● 隔离性:事务的执行是相互独立的,它们不会相互干扰,一个事务不会看到另一个正在运行过程中的事务的数据
● 持久性:一个事务完成之后,事务的执行结果必须是落盘在数据库持久
分布式基本理论
1、CAP 定理
CAP是指一致性(Consistency)、可用性(Availability)和分区容忍性(Partition Tolerance)三个属性,它们是分布式系统设计中的重要概念。
● 一致性(Consistency):
在分布式系统中的所有数据结点,在同一时刻是否同样的值。如果在某个节点更新了数据,那么在其他节点如果都能读取到这个最新的数据,那么就称为强一致,如果有某个节点没有读取到,那就是分布式不一致;
● 可用性(Availability):
在集群中一部分节点故障后,非故障的节点在合理的时间内返回合理的响应。合理的时间指的是请求不能无限被阻塞,应该在合理的时间给出返回;合理的响应指的是系统应该明确返回结果并且结果是正确的;
● 分区容错性(Partition tolerance):
系统能够在节点之间发生网络分区(Partition)的情况下仍然能够正常运行;
在分布式系统中,网络无法100%可靠,分区其实是一个必然现象,如果我们选择了CA而放弃了P,那么当发生分区现象时,为了保证一致性,这个时候必须拒绝请求,但是A又不允许,所以分布式系统理论上不可能选择CA架构,只能选择CP或者AP架构。
对于CP来说,放弃可用性,追求一致性(强一致性)和分区容错性;对于AP来说,放弃一致性,追求分区容错性和可用性,这是很多分布式系统设计时的选择,BASE是根据AP来扩展。在实际应用中,网络延迟和不可靠性是不可避免的,数据复制和同步需要一定的时间。因此,即使选择了保证一致性和分区容忍性(CP),在发生网络分区时,节点之间的数据复制可能会产生一定的延迟,导致节点之间的数据不一致,所以很多业务场景我们退而求用户能接受时间延迟的最终一致方案。
2、BASE理论
根据CAP定理,如果要完整的实现事务的ACID特性,只能放弃可用性选择一致性,然而可用性在现在互联网环境至关重要,BASE 理论是对 CAP 中一致性和可用性权衡的结果,是CAP中AP的一个扩展。其核心思想是:强一致性无法得到保障时,我们可以根据业务自身的特点,采用适当的方式来达到最终一致性。BASE 是 Basically Available(基本可用)、Soft state(软状态)和 Eventually consistent (最终一致性)三个短语的缩写。
● BA:(Basically Available)基本可用性,分布式系统在面对故障或分区的情况下,仍然能够保证基本的可用性。即系统可以继续运行并提供核心的功能,而不是完全崩溃;
● S:(Soft State)软状态,分布式系统中的数据状态不需要实时保持一致,而是允许一段时间的数据不一致。数据状态可以是中间状态,可以根据系统自身的需要而变化,这种状态允许一定的延迟和不一致性;
● E:(Eventually Consistency)最终一致性,经过一段时间后数据最终会达到一致状态,但不要求实时的一致性。
分布式事务方案
指事务的操作位于不同的节点上,需要保证事务的 ACID 特性。
例如在下单场景下,库存和订单如果不在同一个节点上,就涉及分布式事务。
分布式锁和分布式事务区别:
- 锁问题的关键在于进程操作的互斥关系,例如多个进程同时修改账户的余额,如果没有互斥关系则会导致该账户的余额不正确。
- 而事务问题的关键则在于事务涉及的一系列操作需要满足 ACID 特性,例如要满足原子性操作则需要这些操作要么都执行,要么都不执行。
#2PC
两阶段提交(Two-phase Commit,2PC),通过引入协调者(Coordinator)来协调参与者的行为,并最终决定这些参与者是否要真正执行事务。
#1. 运行过程
#1.1 准备阶段
协调者询问参与者事务是否执行成功,参与者发回事务执行结果。询问可以看成一种投票,需要参与者都同意才能执行。
#1.2 提交阶段
如果事务在每个参与者上都执行成功,事务协调者发送通知让参与者提交事务;否则,协调者发送通知让参与者回滚事务。
需要注意的是,在准备阶段,参与者执行了事务,但是还未提交。只有在提交阶段接收到协调者发来的通知后,才进行提交或者回滚。
#2. 存在的问题
#2.1 同步阻塞
所有事务参与者在等待其它参与者响应的时候都处于同步阻塞等待状态,无法进行其它操作。
#2.2 单点问题
协调者在 2PC 中起到非常大的作用,发生故障将会造成很大影响。特别是在提交阶段发生故障,所有参与者会一直同步阻塞等待,无法完成其它操作。
#2.3 数据不一致
在提交阶段,如果协调者只发送了部分 Commit 消息,此时网络发生异常,那么只有部分参与者接收到 Commit 消息,也就是说只有部分参与者提交了事务,使得系统数据不一致。
#2.4 太过保守
任意一个节点失败就会导致整个事务失败,没有完善的容错机制。
3PC
3PC,三阶段提交协议,是二阶段协议的改进版本,三阶段提交有两个改动点:
-
在协调者和参与者中都引入超时机制
-
在第一阶段和第二阶段中插入一个
准备阶段
,保证了在最后提交阶段之前各个参与节点的状态是一致的
所以3PC会分3个阶段,CanCommit准备阶段,PreCommit预提交阶段,DoCommit提交阶段,处理流程如下:
#本地消息表
本地消息表与业务数据表处于同一个数据库中,这样就能利用本地事务来保证在对这两个表的操作满足事务特性,并且使用了消息队列来保证最终一致性。
- 在分布式事务操作的一方完成写业务数据的操作之后向本地消息表发送一个消息,本地事务能保证这个消息一定会被写入本地消息表中。
- 之后将本地消息表中的消息转发到消息队列中,如果转发成功则将消息从本地消息表中删除,否则继续重新转发。
- 在分布式事务操作的另一方从消息队列中读取一个消息,并执行消息中的操作。
TCC
TCC原理
• Try: 尝试执行阶段,完成所有业务可执行性的检查(保障一致性),并且预留好事务需要用到的所有业务资源(保障隔离性)。
• Confirm: 确认执行阶段,不进行任何业务检查,直接使用Try阶段准备的资源来完成业务处理。注意,Confirm
阶段可能会重复执行,因此需要满足幂等性。
• Cancel: 取消执行阶段,释放Try阶段预留的业务资源。注意,Cancel
阶段也可能会重复执行,因此也需要满足幂等性。
开源的TCC解决方案
1、tcc-transaction、ByteTCC
、hmily
、spring-cloud-rest-tcc
分布式事务Seata原理2、Seata:分布式事务Seata原理
Seata 是一款开源的分布式事务解决方案,致力于提供高性能与简单易用的分布式事务服务,为用户提供了 AT、TCC、SAGA 和 XA 几种不同的事务模式。
Seata 的核心组件:
在 Seata 中主要有以下三种角色,其中 TM 和 RM 是作为 Seata 的客户端与业务系统集成在一起,TC 作为 Seata 的服务端独立部署:
事务协调器(TC):维护全局事务的运行状态,负责协调并驱动全局提交或回滚
事务管理器(TM):事务发起方,控制全局事务的范围,负责开启一个全局事务,并最终发起全局提交或回滚全局的决议
资源管理器(RM):事务参与方,管理本地事务正在处理的资源,负责向 TC 注册本地事务、汇报本地事务状态,接收 TC 的命令来驱动本地事务的提交或回滚
Seata的TCC 模式
TCC 模式 RM 驱动分支事务的行为分为以下两个阶段:
(1)执行阶段:
-
① 向 TC 注册分支。
-
② 执行业务定义的 Try 方法。
-
③ 向 TC 上报 Try 方法执行情况:成功或失败。
(2)完成阶段:
-
全局提交,收到 TC 的分支提交请求,执行业务定义的 Confirm 方法。
-
全局回滚,收到 TC 的分支回滚请求,执行业务定义的 Cancel 方法。
参考: