分布式事务
分布式事务

1.事务的概念
事务处理可以用来维护数据库的完整性,保证成批的 SQL 语句要么全部执行,要么全部不执行。

2.事务的特性
事务是必须满足4个条件(ACID):原子性(Atomicity,或称不可分割性)、一致性(Consistency)、隔离性(Isolation,又称独立性)、持久性(Durability)。

  • 原子性:一个事务(transaction)中的所有操作,要么全部完成,要么全部不完成,不会结束在中间某个环节。事务在执行过程中发生错误,会被回滚(Rollback)到事务开始前的状态,就像这个事务从来没有执行过一样。
  • 一致性:在事务开始之前和事务结束以后,数据库的完整性没有被破坏。这表示写入的资料必须完全符合所有的预设规则,这包含资料的精确度、串联性以及后续数据库可以自发性地完成预定的工作。
  • 隔离性:数据库允许多个并发事务同时对其数据进行读写和修改的能力,隔离性可以防止多个事务并发执行时由于交叉执行而导致数据的不一致。事务隔离分为不同级别,包括读未提交(Read uncommitted)、读提交(read committed)、可重复读(repeatable read)和串行化(Serializable)。
  • 持久性:事务处理结束后,对数据的修改就是永久的,即便系统故障也不会丢失。



3.分布式事务
随着互联网快速发展,微服务,SOA 等服务架构模式正在被大规模的使用,现在分布式系统一般由多个独立的子系统组成,多个子系统通过网络通信互相协作配合完成各个功能。
有很多用例会跨多个子系统才能完成,比较典型的是电子商务网站的下单支付流程,至少会涉及交易系统和支付系统。
而且这个过程中会涉及到事务的概念,即保证交易系统和支付系统的数据一致性,此处我们称这种跨系统的事务为分布式事务。
具体一点而言,分布式事务是指事务的参与者、支持事务的服务器、资源服务器以及事务管理器分别位于不同的分布式系统的不同节点之上,需要保证事务的 AICD 特性。

4.分布式事务的难点
事务的原子性
事务操作跨不同节点,当多个节点某一节点操作失败时,需要保证多节点操作的要么什么都不做,要么做全套(All or Nothing)的原子性。
事务的一致性
当发生网络传输故障或者节点故障,节点间数据复制通道中断,在进行事务操作时需要保证数据一致性,保证事务的任何操作都不会使得数据违反数据库定义的约束、触发器等规则。
事务的隔离性
事务隔离性的本质就是如何正确处理多个并发事务的读写冲突和写写冲突,因为在分布式事务控制中,可能会出现提交不同步的现象,这个时候就有可能出现“部分已经提交”的事务。
此时并发应用访问数据如果没有加以控制,有可能出现“脏读”问题。

5. 分布式事务的理论基础
5.1. CPA理论
在一个分布式系统(指互相连接并共享数据的节点的集合)中,当涉及读写操作时,只能保证一致性(Consistence)、可用性(Availability)、分区容错性(Partition Tolerance)三者中的两个,另外一个必须被牺牲。
3e443c7efa1f44a7aac25eee3ba0f67e.jpeg



C - Consistency 一致性:
当用户写入一个值1之后,不管请求哪个节点,得到的值都应该是1,是一致的。
A - Availability 可用性:
当用户请求的时候,就应该给出返回值。
P - Partition Tolerance 分区容忍性:
应用分布在不同的节点,节点与节点之间通过网络通信。
5.1.1 C-A-P的选择
理论上来说,一致性,可用性,分区容错性只能三取其二。但是,分布式系统中,分区容错性是必须保证的,那么,就只能在CP,AP 中间作出选择。这里的选择是指同时选择,而最终的CAP还是要达到的。
①CP - Consistency + Partition Tolerance (一致性 + 分区容忍性)
②AP - Availability + Partition Tolerance (可用性 + 分区容忍性)

5.2CAP 理论的延伸:BASE 理论
c4995d33789e4094a6c4b3f2118b4f8e.png

BASE 是指基本可用(Basically Available)、软状态( Soft State)、最终一致性( Eventual Consistency)。
它的核心思想是即使无法做到强一致性(CAP 的一致性就是强一致性),但应用可以采用适合的方式达到最终一致性。
5.2.1 BA - Basically Available 基本可用
分布式系统在出现故障时,允许损失部分可用性,即保证核心可用。
这里的关键词是“部分”和“核心”,实际实践上,哪些是核心需要根据具体业务来权衡。
例如登录功能相对注册功能更加核心,注册不了最多影响流失一部分用户,如果用户已经注册但无法登录,那就意味着用户无法使用系统,造成的影响范围更大。
5.2.2 S - Soft State 软状态
允许系统存在中间状态,而该中间状态不会影响系统整体可用性。这里的中间状态就是 CAP 理论中的数据不一致。
5.2.3 E - Eventual Consistency 最终一致性
系统中的所有数据副本经过一定时间后,最终能够达到一致的状态。
这里的关键词是“一定时间” 和 “最终”,“一定时间”和数据的特性是强关联的,不同业务不同数据能够容忍的不一致时间是不同的。
例如支付类业务是要求秒级别内达到一致,因为用户时时关注;用户发的最新微博,可以容忍 30 分钟内达到一致的状态,因为用户短时间看不到明星发的微博是无感知的。
而“最终”的含义就是不管多长时间,最终还是要达到一致性的状态。
BASE 理论本质上是对 CAP 的延伸和补充,更具体地说,是对 CAP 中 AP 方案的一个补充:CAP 理论是忽略延时的,而实际应用中延时是无法避免的。
这一点就意味着完美的 CP 场景是不存在的,即使是几毫秒的数据复制延迟,在这几毫秒时间间隔内,系统是不符合 CP 要求的。
因此 CAP 中的 CP 方案,实际上也是实现了最终一致性,只是“一定时间”是指几毫秒而已。
AP 方案中牺牲一致性只是指发生分区故障期间,而不是永远放弃一致性。
这一点其实就是 BASE 理论延伸的地方,分区期间牺牲一致性,但分区故障恢复后,系统应该达到最终一致性。

5.3 数据一致性模型
前面介绍的 BASE 模型提过“强一致性”和“最终一致性”,下面对这些一致性模型展开介绍。
分布式系统通过复制数据来提高系统的可靠性和容错性,并且将数据的不同的副本存放在不同的机器上,由于维护数据副本的一致性代价很高,因此许多系统采用弱一致性来提高性能。
下面介绍常见的一致性模型:

  • 强一致性:要求无论更新操作是在哪个数据副本上执行,之后所有的读操作都要能获得最新的数据。 对于单副本数据来说,读写操作是在同一数据上执行的,容易保证强一致性。对多副本数据来说,则需要使用分布式事务协议。
  • 弱一致性:在这种一致性下,用户读到某一操作对系统特定数据的更新需要一段时间,我们将这段时间称为"不一致性窗口"。
  • 最终一致性:是弱一致性的一种特例,在这种一致性下系统保证用户最终能够读取到某操作对系统特定数据的更新(读取操作之前没有该数据的其他更新操作)。 "不一致性窗口"的大小依赖于交互延迟、系统的负载,以及数据的副本数等。

系统选择哪种一致性模型取决于应用对一致性的需求,所选取的一致性模型还会影响到系统如何处理用户的请求以及对副本维护技术的选择等。
后面将基于上面介绍的一致性模型分别介绍分布式事务的解决方案。

6. 柔性事务
柔性事务的概念
在电商等互联网场景下,传统的事务在数据库性能和处理能力上都暴露出了瓶颈。在分布式领域基于 CAP 理论以及 BASE 理论,有人就提出了柔性事务的概念。
基于 BASE 理论的设计思想,柔性事务下,在不影响系统整体可用性的情况下(Basically Available 基本可用),允许系统存在数据不一致的中间状态(Soft State 软状态),在经过数据同步的延时之后,最终数据能够达到一致。
并不是完全放弃了 ACID,而是通过放宽一致性要求,借助本地事务来实现最终分布式事务一致性的同时也保证系统的吞吐。
实现柔性事务的一些特性
下面介绍的是实现柔性事务的一些常见特性,这些特性在具体的方案中不一定都要满足,因为不同的方案要求不一样。
可见性(对外可查询) :在分布式事务执行过程中,如果某一个步骤执行出错,就需要明确的知道其他几个操作的处理情况,这就需要其他的服务都能够提供查询接口,保证可以通过查询来判断操作的处理情况。
为了保证操作的可查询,需要对于每一个服务的每一次调用都有一个全局唯一的标识,可以是业务单据号(如订单号)、也可以是系统分配的操作流水号(如支付记录流水号)。除此之外,操作的时间信息也要有完整的记录。
操作幂等性:幂等性,其实是一个数学概念。幂等函数,或幂等方法,是指可以使用相同参数重复执行,并能获得相同结果的函数。
幂等操作的特点是其任意多次执行所产生的影响均与一次执行的影响相同。也就是说,同一个方法,使用同样的参数,调用多次产生的业务结果与调用一次产生的业务结果相同。
之所以需要操作幂等性,是因为为了保证数据的最终一致性,很多事务协议都会有很多重试的操作,如果一个方法不保证幂等,那么将无法被重试。
幂等操作的实现方式有多种,如在系统中缓存所有的请求与处理结果、检测到重复操作后,直接返回上一次的处理结果等。

7. 分布式事务的几种解决方案
介绍完分布式系统的一致性相关理论,下面基于不同的一致性模型介绍分布式事务的常见解决方案,后面会再介绍各个方案的使用场景。
分布式事务的实现有许多种,主要模式有 AT,TCC,SAGA和XA
7.1 AT 模式。
AT模式是基于本地数据库的事务机制的一个无侵入方案,seata实现了AT模式。
整体机制
两阶段提交协议的演变:

  • 一阶段:业务数据和回滚日志记录在同一个本地事务中提交,释放本地锁和连接资源。
  • 二阶段:
  • 提交异步化,非常快速地完成。
  • 回滚通过一阶段的回滚日志进行反向补偿。

写隔离

  • 一阶段本地事务提交前,需要确保先拿到 全局锁 。
  • 拿不到 全局锁 ,不能提交本地事务。
  • 拿 全局锁 的尝试被限制在一定范围内,超出范围将放弃,并回滚本地事务,释放本地锁。

简单的来说,就是会有一个全局的事务管理,每次事务都会记录操作前和操作后的数据,如果所有的分支事务都成功,则事务管理通知删除操作记录数据,如果有分支事务失败,则通知所有分支回滚(恢复到操作前的数据)。

7.2 TCC模式
TCC 模式,不依赖于底层数据资源的事务支持:

  • 一阶段 prepare 行为:调用 自定义 的 prepare 逻辑。
  • 二阶段 commit 行为:调用 自定义 的 commit 逻辑。
  • 二阶段 rollback 行为:调用 自定义 的 rollback 逻辑。

seata_tcc-1.png

TCC模式可以概括为:将业务分为两段,以转账为例A要向B转30元,单体应用中,就是一个事务下,A余额减30,B的余额加30。但是,在分布式场景下,按照TCC的模式,一阶段,先要将A账户中的30元冻结,这个时候被冻结部分的钱不能被使用,二阶段,如果执行commit ,则进行真实的扣除,B用户余额增加,如果执行cancel ,则释放被冻结部分的金额。

7.3 saga模式
Saga模式是SEATA提供的长事务解决方案,在Saga模式中,业务流程中每个参与者都提交本地事务,当出现某一个参与者失败则补偿前面已经成功的参与者,一阶段正向服务和二阶段补偿服务都由业务开发实现。
理论基础:Hector & Kenneth 发表论⽂ Sagas (1987)
TB1hSpccIVl614jSZKPXXaGjpXa-1330-924.png

saga模式就是最终一致性解决方案,中间的状态可能会不一致。每个操作一般都会有对应的补偿业务。例如,A->B->C-失败->C回滚->B回滚->A回滚。所以saga的模式,更多的需要自己去控制 比如:某个环境失败,可以重试几次,如果一直失败,再回滚。

7.4 XA模式
XA是X/Open DTP组织(X/Open DTP group)定义的两阶段提交协议,XA被许多数据库(如Oracle、DB2、SQL Server、MySQL)和中间件等工具(如CICS 和 Tuxedo)本地支持 。
X/Open DTP模型(1994)包括应用程序(AP)、事务管理器(TM)、资源管理器(RM)。
TB1Y2kuw7T2gK0jSZFkXXcIQFXa-445-444.png

之前我们在单体应用中所用到的多数据源之间的事务框架atomikos 就是基于XA模式的。

四种分布式事务模式,分别在不同的时间被提出,每种模式都有它的适用场景

  • AT 模式是无侵入的分布式事务解决方案,适用于不希望对业务进行改造的场景,几乎0学习成本。
  • TCC 模式是高性能分布式事务解决方案,适用于核心系统等对性能有很高要求的场景。
  • Saga 模式是长事务解决方案,适用于业务流程长且需要保证事务最终一致性的业务系统,Saga 模式一阶段就会提交本地事务,无锁,长流程情况下可以保证性能,多用于渠道层、集成层业务系统。事务参与者可能是其它公司的服务或者是遗留系统的服务,无法进行改造和提供 TCC 要求的接口,也可以使用 Saga 模式。
  • XA模式是分布式强一致性的解决方案,但性能低而使用较少。



8. 框架支持
在实际项目中,我们一般会去寻找是否有框架能支持。支持分布式事务的框架目前有阿里的seata,另外shardingsphere也提供基于XA的分布式事务和基于seata的分布式事务。

参考资料:
http://www.ruanyifeng.com/blog/2018/07/cap.html
http://dockone.io/article/9132
https://www.jianshu.com/p/ee4071d0c951
https://blog.csdn.net/john1337/article/details/97551499
https://www.zhihu.com/tardis/sogou/art/78599954
https://www.cnblogs.com/zjfjava/p/10425335.html

暂无评论