一、前言
通过以下系列章节:
docker-compose 实现Seata Server高可用部署 | Spring Cloud 51
Seata AT 模式理论学习、事务隔离及部分源码解析 | Spring Cloud 52
Spring Boot集成Seata利用AT模式分布式事务示例 | Spring Cloud 53
Seata XA 模式理论学习、使用及注意事项 | Spring Cloud54
Seata TCC 模式理论学习、生产级使用示例搭建及注意事项 | Spring Cloud55
Seata TCC 模式下解决幂等、悬挂、空回滚问题 | Spring Cloud56
Seata Saga 模式理论学习、生产级使用示例搭建及注意事项(一) | Spring Cloud57
Seata Saga 模式理论学习、生产级使用示例搭建及注意事项(二) | Spring Cloud58
我们对Seata
及其AT
、XA
、TCC
、Saga
事务模式的理论、使用有了深入的了解,今天分布式基础理论和Seata
的四种模式进行对比总结。
二、事务
事务简单理解就是更新数据库中各种数据的一个程序执行单元(unit
),一个事务严格上必须具备原子性、一致性、隔离性和持久性,简称 ACID
。
-
原子性(
Atomicity
):一个事务内的所有操作要么都执行,要么都不执行。 -
一致性(
Consistency
):一致性是指事务必须使数据库从一个一致性状态变换到另一个一致性状态,即数据库处理前后结果应与根据业务规则执行后的结果保持一致。 -
隔离性(
Isolation
):指的是多个事务并发执行的时候不会互相干扰。 -
持久性(
Durability
):指的是一个事务完成了之后数据就被永远保存下来,之后的其他操作或故障都不会对事务的结果产生影响。
三、分布式事务
分布式事务顾名思义就是要在分布式系统中实现事务,它由多个本地事务组合而成。
使用分布式事务的根源:高并发,当一台服务器忙不过来,需要增加多服务器来帮忙响应请求。这时候就会出现一个问题,就是数据只有一份,如何保证分布式环境下,每个事物执行过后,数据都是正确的,比如库存服务,订单服务,支付服务,他们分别部署,这个时候做一次购买完成就需要这三个服务都需要完成相应的操作,要么一起失败,要么一起成功。这就引出了分布式事务的解决问题。
四、CAP理论
在一个分布式系统中,一致性(Consistency
)、可用性(Availability
)、分区容错性(Partition tolerance
),这三个要素最多只能同时实现两点,不可能三者兼顾。
-
一致性(
Consistency
):在分布式系统中的所有数据备份,在同一时刻是否同样的值。(等同于所有节点访问同一份最新的数据副本) -
可用性(
Availability
):在集群中一部分节点故障后,集群整体是否还能响应客户端的读写请求。(对数据更新具备高可用性) -
分区容忍性(
Partition
tolerance):以实际效果而言,分区相当于对通信的时限要求。系统如果不能在时限内达成数据一致性,就意味着发生了分区的情况,必须就当前操作在C和A之间做出选择
图中重叠的部分就是在分布式环境下,必须做出的取舍:要么CP
,要么AP
,要么CA
,但是不存在CAP
。
CP
:牺牲可用性。复制同步的协议一般使用严格的法定数协议 (Paxos
、Raft
、ZAB
)或者2PC
协议。CP
类型的系统有MongoDB
、HBase
、 Zookeeper
、Redis
、ElasticSearch
等。
AP
:牺牲一致性。复制同步的协议一般使用非严格的法定数协议。AP
类型的系统有 Couch DB
、Cassandra
、Amazon Dynamo
等。
CA
:抛开RDBMS
的Oracle
和MySQL
不谈,分布式系统中宣称是CA
系统的有谷歌的Spanner
和阿里的OceanBase
。
问:为什么分布式系统中无法同时保证一致性和可用性?
答:首先一个前提,对于分布式系统而言,分区容错性是一个最基本的要求,因此基本上我们在设计分布式系统的时候只能从一致性(
C
)和可用性(A
)之间进行取舍。如果保证了一致性(
C
):对于节点N1
和N2
,当往N1
里写数据时,N2
上的操作必须被暂停,只有当N1
同步数据到N2
时才能对N2
进行读写请求,在N2
被暂停操作期间客户端提交的请求会收到失败或超时。显然,这与可用性是相悖的。如果保证了可用性(
A
):那就不能暂停N2
的读写操作,但同时N1
在写数据的话,这就违背了一致性的要求。
CAP
和ACID
中的A
和C
是完全不一样的:
-
C
的区别:-
ACID
一致性是有关数据库规则,数据库总是从一个一致性的状态转换到另外一个一致性的状态; -
CAP
的一致性是分布式多服务器之间复制数据令这些服务器拥有同样的数据,由于网速限制,这种复制在不同的服务器上所消耗的时间是不固定的,集群通过组织客户端查看不同节点上还未同步的数据维持逻辑视图,这是一种分布式领域的一致性概念;
-
-
A
的区别:-
ACID
中的A
指的是原子性(Atomicity
),是指事务被视为一个不可分割的最小工作单元,事务中的所有操作要么全部提交成功,要么全部失败回滚; -
CAP
中的A
指的是可用性(Availability
),是指集群中一部分节点故障后,集群整体是否还能响应客户端的读写请求;
-
五、BASE理论
BASE
是Basically Available
(基本可用)、Soft state
(软状态)和Eventually consistent
(最终一致性)的缩写。
在分布式系统中,CAP
理论是指导思维,而BASE
理论是CAP
理论中AP
的延伸,是对 CAP
中的一致性和可用性进行一个权衡的结果,核心思想是:即使无法做到强一致性,但每个应用都可以根据自身的业务特点,采用适当的方式来使系统达到最终一致性。
-
基本可用(
Basically Available
):指分布式系统在出现故障的时候,允许损失部分可用性,保证核心可用。 -
柔性状态(
Soft state)
:指允许系统存在中间状态,并认为该中间状态不会影响系统整体可用性。比如,允许不同节点间副本同步的延时就是柔性状态的体现。 -
最终一致性(
Eventually consistent
):指系统中的所有副本经过一定时间后,最终能够达到一致的状态。因此,最终一致性的本质是需要系统保证最终数据能够达到一致,而不需要实时保证系统数据的强一致性。
六、事务的一致性
-
强一致性:系统中的某个数据被成功更新后,后续的访问都能看到更新后的值。
-
弱一致性:系统中的某个数据被更新后,后续的访问可能得到更新后的值,也可能是更改前的值。
-
最终一致性:系统中的某个数据被更新,经过一段时间后,最终所有的访问都是更新的值。
刚性事务:遵循
ACID
原则,强一致性。
柔性事务:遵循
BASE
理论,最终一致性。
七、Seata
Seata
是 2019 年 1 月份蚂蚁金服和阿里巴巴共同开源的分布式事务解决方案。致力于提供高性能和简单易用的分布式事务服务,为用户打造一站式的分布式解决方案。
官网地址:http://seata.io/,其中的文档、播客中提供了大量的使用说明、源码分析。
7.1 架构
Seata
事务管理中有三个重要的角色:
-
TC
(Transaction Coordinator
) - 事务协调者:维护全局和分支事务的状态,协调全局事务提交或回滚。 -
TM
(Transaction Manager
) - 事务管理器:定义全局事务的范围、开始全局事务、提交或回滚全局事务。 -
RM
(Resource Manager
) - 资源管理器:管理分支事务处理的资源,与TC交谈以注册分支事务和报告分支事务的状态,并驱动分支事务提交或回滚
Seata
基于上述架构提供了四种不同的分布式事务解决方案:
-
XA
模式:强一致性分阶段事务模式,牺牲了一定的可用性,无业务侵入 -
TCC
模式:最终一致的分阶段事务模式,有业务侵入 -
AT
模式:最终一致的分阶段事务模式,无业务侵入,也是Seata的默认模式 -
SAGA
模式:长事务模式,有业务侵入
7.2 XA 模式
7.2.1 整体机制
在 Seata
定义的分布式事务框架内,利用事务资源(数据库、消息服务等)对 XA
协议的支持,以 XA
协议的机制来管理分支事务的一种 事务模式。
RM一阶段的工作:
① 注册分支事务到TC
② 执行分支业务sql但不提交
③ 报告执行状态到TC
TC二阶段的工作:
-
TC检测各分支事务执行状态
- a.如果都成功,通知所有RM提交事务
- b.如果有失败,通知所有RM回滚事务
RM二阶段的工作:
- 接收TC指令,提交或回滚事务
7.2.2 优缺点
-
XA模式的优点是什么?
-
事务的强一致性,满足ACID原则。
-
常用数据库都支持,实现简单,并且没有代码侵入
-
-
XA模式的缺点是什么?
-
因为一阶段需要锁定数据库资源,等待二阶段结束才释放,性能较差
-
依赖关系型数据库实现事务
-
7.3 AT 模式
7.3.1 整体机制
AT
模式是两阶段提交协议的演变(最终一致的分阶段事务模式)。弥补了XA
模式中资源锁定周期过长的缺陷。
阶段一RM
的工作:
-
注册分支事务
-
记录
undo-log
(数据快照) -
执行业务
sql
并提交 -
报告事务状态
阶段二提交时RM
的工作:
- 删除
undo-log
即可
阶段二回滚时RM
的工作:
- 根据
undo-log
恢复数据到更新前
7.3.2 AT与XA的区别
-
XA
模式一阶段不提交事务,锁定资源;AT
模式一阶段直接提交,不锁定资源。 -
XA
模式依赖数据库机制实现回滚;AT
模式利用数据快照实现数据回滚。 -
XA
模式强一致;AT
模式最终一致。
7.4 TCC 模式
7.4.1 整体机制
整体是 两阶段提交 的模型。全局事务是由若干分支事务组成的,分支事务要满足 两阶段提交 的模型要求,即需要每个分支事务都具备自己的:
- 一阶段
Try
行为 - 二阶段
Confirm
或Cancel
行为
上面这个流程中,一共涉及到了三个方法,Try
、Confirm
以及 Cancel
,这三个方法都完全是用户自定义的方法,都是需要我们自己来实现的。相较于 AT
事务模式 TCC
这种模式其实是不依赖于底层数据库的事务支持的。
7.4.2 优缺点
TCC
模式的每个阶段是做什么的?
-
Try
:资源检查和预留 -
Confirm
:业务执行和提交 -
Cancel
:预留资源的释放
TCC
的优点是什么?
-
一阶段完成直接提交事务,释放数据库资源,性能好
-
相比AT模型,无需生成快照,无需使用全局锁,性能最强
-
不依赖数据库事务,而是依赖补偿操作,可以用于非事务型数据库
TCC
的缺点是什么?
-
有代码侵入,需要人为编写try、Confirm和Cancel接口,太麻烦
-
软状态,事务是最终一致
-
需要考虑
Confirm
和Cancel
的失败情况,做好幂等处理
7.5 Saga 模式
7.5.1 整体机制
Saga
模式是Seata
提供的长事务解决方案,在Saga
模式中,业务流程中每个参与者都提交本地事务,当出现某一个参与者失败则补偿前面已经成功的参与者,一阶段正向服务和二阶段补偿服务都由业务开发实现。
理论基础:Hector & Kenneth 发表论⽂ Sagas (1987)
7.5.2 优缺点
- 适用场景:
- 业务流程长、业务流程多
- 参与者包含其它公司或遗留系统服务,无法提供 TCC 模式要求的三个接口
- 优势:
- 一阶段提交本地事务,无锁,高性能
- 事件驱动架构,参与者可异步执行,高吞吐
- 补偿服务易于实现
- 缺点:
- 不保证隔离性
八、Seata 四种模式对比
- | XA | AT | TCC | SAGA |
---|---|---|---|---|
一致性 | 强一致 | 弱一致 | 弱一致 | 最终一致 |
隔离性 | 完全隔离 | 基于全局锁隔离 | 基于资源预留隔离 | 无隔离 |
代码侵入 | 无 | 无 | 有,要编写三个接口 | 有,要编写状态机和补偿业务 |
性能 | 差 | 好 | 非常好 | 非常好 |
场景 | 对一致性、隔离性有高要求的业务 | 基于关系型数据库的大多数分布式事务场景都可以 | 对性能要求较高的事务、对非关系型数据参与的事务 | 业务流程长、业务流程多,参与者包含其他公司或遗留系统服务,无法提供TCC 模式要求的三个接口 |