1、本地事务
关于本地事务相关概念请参考《数据库事务Transaction》和《MySQL实现架构、事务概述、锁机制》。在这两篇文章中,主要讲解了本地事务的基本概念、ACID特性和隔离级别等内容。
2、分布式事务
在传统的单节点应用中,本地事务就可以满足需求了。但随着互联网时代的到来,数据量的急剧增加、服务复杂程度越来越高,为了解决这些问题,分库分表、微服务架构等技术或思想就应用而生了,这个时候,多个服务资源或多个数据库资源就需要在同一个事务中进行管理了,但是本地事务却对此无能为力,所以分布式事务就出现了。
2.1、应用场景
1、跨库事务
跨库事务指的是,一个应用某个功能需要操作多个库,不同的库中存储不同的业务数据。下图演示了一个服务同时操作2个库的情况:
2、分库分表
通常一个库数据量比较大或者预期未来的数据量比较大,都会进行水平拆分,也就是分库分表。如下图,将数据库B拆分成了2个库:
3、服务化(SOA)
微服务架构是目前一个比较一个比较火的概念。对比比较复杂的应用系统,一般会拆分成不同的独立服务,以简化业务逻辑。拆分后,独立服务之间通过RPC框架来进行远程调用,实现彼此的通信。下图演示了一个3个服务之间彼此调用的架构:
上述内容来自《分布式事务概述》。
2.2、CAP原理
- C – Consistent ,一致性。具体是指,操作成功以后,所有的节点,在同一时间,看到的数据都是完全一致的。所以,一致性,说的就是数据一致性。
- A – Availability ,可用性。指服务一致可用,在规定的时间内完成响应。
- P – Partition tolerance ,分区容错性。指分布式系统在遇到某节点或网络分区故障的时候,仍然能够对外提供服务。
CAP原理指出,这3个指标不能同时满足,最多只能满足其中的两个。
我们之所以使用分布式系统,就是为了在某个节点不可用的情况下,整个服务对外还是可用的,这正是满足P(分区容错性)。如果我们的服务不满足P(分区容错性),那么我们的系统也就不是分布式系统了,所以,在分布式系统中,P(分布容错性)总是成立的。
A和B是两个数据节点,A向B同步数据,并且作为一个整体对外提供服务。由于我们的系统保证了P(分区容错性),那么A和B的同步,我们允许出现故障。接下来我们再保证A(可用性),也就是说A和B同步出现问题时,客户端还能够访问我们的系统,那么客户端既可能访问A也可能访问B,这时,A和B的数据是不一致的,所以C(一致性)不能满足。
如果我们满足C(一致性),也就是说客户端无论访问A还是访问B,得到的结果都是一样的,那么现在A和B的数据不一致,需要等到A和B的数据一致以后,也就是同步恢复以后,才可对外提供服务。这样我们虽然满足了C(一致性),却不能满足A(可用性)。
所以,我们的系统在满足P(分区容错性)的同时,只能在A(可用性)和C(一致性)当中选择一个不能CAP同时满足。我们的分布式系统只能是AP或者CP。
2.3、X/Open DTP模型(Distributed Transaction Processing)
1、模型元素
在《Distributed Transaction Processing: Reference Model》第3版中,规定了构成DTP模型的5个基本元素:
- 应用程序(Application Program ,简称AP):用于定义事务边界(即定义事务的开始和结束),并且在事务边界内对资源进行操作。
- 资源管理器(Resource Manager,简称RM):如数据库、文件系统等,并提供访问资源的方式。
- 事务管理器(Transaction Manager ,简称TM):负责分配事务唯一标识,监控事务的执行进度,并负责事务的提交、回滚等。
- 通信资源管理器(Communication Resource Manager,简称CRM):控制一个TM域(TM domain)内或者跨TM域的分布式应用之间的通信。
- 通信协议(Communication Protocol,简称CP):提供CRM提供的分布式应用节点之间的底层通信服务。
其中由于通信资源管理器(Communication Resource Manager)和通信协议(Communication Protocol)是一对好基友,从Communication Protocol的简称CP上就可以看出来,两个元素的关系不一般,因此有的文章在介绍DTP模型元素时,只提到了通信资源管理器…
2、模型实例(Instance of the Model)
一个DTP模型实例,至少有3个组成部分:AP、RMs、TM。如上图所示,一般用于跨库事务处理,即当个应用操作多个库,在这里就是一个AP需要操作多个RM上的资源。AP通过TM来声明一个全局事务,然后操作不同的RM上的资源,最后通知TM来提交或者回滚全局事务。
如果分布式事务中需要跨多个服务,类似于前面提到的SOA场景,这个时候就需要引入通信资源管理器CRM,如下所示:
2.4、XA规范
XA规范的最主要的作用是,就是定义了RM-TM的交互接口。
XA Interface
XA规范中定义的RM 和 TM交互的接口如下图所示:
2.5、BASE原理
BASE是Basically Available(基本可用), Soft-state(软状态), Eventually consistent(最终一致)的缩写。
- Basically Available,基本可用是指分布式系统在出现故障的时候,允许损失部分可用性,即保证核心可用。电商大促时,为了应对访问量激增,部分用户可能会被引导到降级页面,服务层也可能只提供降级服务。这就是损失部分可用性的体现。
- 软状态( Soft State)
软状态是指允许系统存在中间状态,而该中间状态不会影响系统整体可用性。分布式存储中一般一份数据至少会有两到三个副本,允许不同节点间副本同步的延时就是软状态的体现。mysql replication的异步复制也是一种体现。 - 最终一致性( Eventual Consistency)
最终一致性是指系统中的所有数据副本经过一定时间后,最终能够达到一致的状态。弱一致性和强一致性相反,最终一致性是弱一致性的一种特殊情况。
BASE模型是传统ACID模型的反面,不同与ACID,BASE强调牺牲高一致性,从而获得可用性,数据允许在一段时间内的不一致,只要保证最终一致就可以了。
在分布式事务的解决方案中,它们都是依赖了ACID或者BASE的模型而实现的。像基于XA协议的两阶段提交和实物补偿机制就是基于ACID实现的。而基于本地消息表和基于MQ的最终一致方案都是通过BASE原理实现的。
2.6、两阶段提交协议(2PC,Two Phase Commit)
基于XA协议的两阶段提交,由一个事务管理器(TM)和多个资源管理器(RM)组成,然后提交分为两个阶段:prepare和commit。
在第一个阶段,事务管理器(TM)通知资源管理器(RM)提交它们的事务分支,如果RM判断可以提交,就返回肯定答复,否则,就返回否定答复。发送否定答复前,需要回滚当前分支的事务。对于mysql数据库来说,在第一阶段,事务管理器向所有涉及到的数据库服务器发出prepare”准备提交”请求,数据库收到请求后执行数据修改和日志记录等处理,处理完成后只是把事务的状态改成”可以提交”,然后把结果返回给事务管理器。
在第二个阶段,事务管理器(TM)根据第一阶段各个资源管理器(RM)返回的结果,决定是提交事务,还是回滚事务。如果所有的RM都prepare成功,那么TM通知所有的RM进行提交;如果有RM prepare失败的话,则TM通知所有RM回滚自己的事务分支。对于mysql数据库来说,如果第一阶段中所有数据库都prepare成功,那么事务管理器向数据库服务器发出”确认提交”请求,数据库服务器把事务的”可以提交”状态改为”提交完成”状态,然后返回应答。如果在第一阶段内有任何一个数据库的操作发生了错误,或者事务管理器收不到某个数据库的回应,则认为事务失败,回撤所有数据库的事务。数据库服务器收不到第二阶段的确认提交请求,也会把”可以提交”的事务回撤。
XA规范对两阶段提交协议有2点优化:
- 只读断言
在Phase 1中,RM可以断言“我这边不涉及数据增删改”来答复TM的prepare请求,从而让这个RM脱离当前的全局事务,从而免去了Phase 2。这种优化发生在其他RM都完成prepare之前的话,使用了只读断言的RM早于AP其他动作(比如说这个RM返回那些只读数据给AP)前,就释放了相关数据的上下文(比如读锁之类的),这时候其他全局事务或者本地事务就有机会去改变这些数据,结果就是无法保障整个系统的可序列化特性——通俗点说那就会有脏读的风险。 - 一阶段提交
如果需要增删改的数据都在同一个RM上,TM可以使用一阶段提交——跳过两阶段提交中的Phase 1,直接执行Phase 2。这种优化的本质是跳过Phase 1,RM自行决定了事务分支的结果,并且在答复TM前就清除掉事务分支信息。对于这种优化的情况,TM实际上也没有必要去可靠的记录全局事务的信息,在一些异常的场景下,此时TM可能不知道事务分支的执行结果。
两阶段提交协议(2PC)存在的问题
- 同步阻塞
两阶段提交执行过程中,所有的参与者都需要听从协调者的统一调度,期间处于阻塞状态而不能从事其他操作,这样效率极其低下。 - 存在数据不一致
在第二阶段提交时,如果出现异常(超时或失败),这个时候可能会导致一部分资源管理接收到了commit请求,提交了事务,一部分资源管理器没有接收到commit请求,导致回滚,最后出现了数据不一致性。 - 事务管理器的单点故障
由于事务管理器的重要性,一旦协调者TM发生故障。参与者RM会一直阻塞下去。
2.7、三阶段提交协议(3PC,Three-phase commit)
三阶段提交(3PC),是二阶段提交(2PC)的改进版本。与两阶段提交相比,主要有以下两点不同:
-
引入超时机制。同时在协调者和参与者中都引入超时机制。
-
在第一阶段和第二阶段中插入一个准备阶段。保证了在最后提交阶段之前各参与节点的状态是一致的。
三阶段提交有CanCommit、PreCommit、DoCommit三个阶段,如上所示。
CanCommit阶段
3PC的CanCommit阶段其实和2PC的准备阶段很像。事务管理器(协调者)向资源管理器(参与者)发送commit请求,参与者如果可以提交就返回Yes响应,否则返回No响应。
1.事务询问 协调者向参与者发送CanCommit请求。询问是否可以执行事务提交操作。然后开始等待参与者的响应。
2.响应反馈 参与者接到CanCommit请求之后,正常情况下,如果其自身认为可以顺利执行事务,则返回Yes响应,并进入预备状态。否则反馈No。
PreCommit阶段
协调者根据参与者的反应情况来决定是否可以继续事务的PreCommit操作。根据响应情况,有以下两种可能:
第一种情况:假如协调者从所有的参与者获得的反馈都是Yes响应,那么就会执行事务的预执行。
-
发送预提交请求 协调者向参与者发送PreCommit请求,并进入Prepared阶段。
-
事务预提交 参与者接收到PreCommit请求后,会执行事务操作,并将undo和redo信息记录到事务日志中。
-
响应反馈 如果参与者成功的执行了事务操作,则返回ACK响应,同时开始等待最终指令。
第二种情况:假如有任何一个参与者向协调者发送了No响应,或者等待超时之后,协调者都没有接到参与者的响应,那么就执行事务的中断。
-
发送中断请求 协调者向所有参与者发送abort请求。
-
中断事务 参与者收到来自协调者的abort请求之后(或超时之后,仍未收到协调者的请求),执行事务的中断。
doCommit阶段
该阶段进行真正的事务提交,也可以分为以下两种情况:
第一种情况:执行提交
-
发送提交请求 协调接收到参与者发送的ACK响应,那么他将从预提交状态进入到提交状态。并向所有参与者发送doCommit请求。
-
事务提交 参与者接收到doCommit请求之后,执行正式的事务提交。并在完成事务提交之后释放所有事务资源。
-
响应反馈 事务提交完之后,向协调者发送Ack响应。
-
完成事务 协调者接收到所有参与者的ack响应之后,完成事务。
第二种情况:中断事务 协调者没有接收到参与者发送的ACK响应(可能是接受者发送的不是ACK响应,也可能响应超时),那么就会执行中断事务。
-
发送中断请求 协调者向所有参与者发送abort请求
-
事务回滚 参与者接收到abort请求之后,利用其在阶段二记录的undo信息来执行事务的回滚操作,并在完成回滚之后释放所有的事务资源。
-
反馈结果 参与者完成事务回滚之后,向协调者发送ACK消息
-
中断事务 协调者接收到参与者反馈的ACK消息之后,执行事务的中断。
2.8、2PC与3PC的区别
相对于2PC,3PC主要解决的单点故障问题,并减少阻塞,因为一旦参与者无法及时收到来自协调者的信息之后,他会默认执行commit。而不会一直持有事务资源并处于阻塞状态。但是这种机制也会导致数据一致性问题,因为,由于网络原因,协调者发送的abort响应没有及时被参与者接收到,那么参与者在等待超时之后执行了commit操作。这样就和其他接到abort命令并执行回滚的参与者之间存在数据不一致的情况。
2.9、TCC 分布式事务
如上图所示:
-
一个完整的业务活动由一个主业务服务与若干从业务服务组成。
-
主业务服务负责发起并完成整个业务活动。
-
从业务服务提供TCC型业务操作。
-
业务活动管理器控制业务活动的一致性,它登记业务活动中的操作,并在业务活动提交时进行confirm操作,在业务活动取消时进行cancel操作
TCC和2PC/3PC很像,不过TCC的事务控制都是业务代码层面的,而2PC/3PC则是资源层面的。
各阶段规范
TCC事务其实主要包含两个阶段:Try阶段、Confirm/Cancel阶段。
从TCC的逻辑模型上我们可以看到,TCC的核心思想是,try阶段检查并预留资源,确保在confirm阶段有资源可用,这样可以最大程度的确保confirm阶段能够执行成功。
-
try-尝试执行业务
完成所有业务检查(一致性)
预留必须业务资源(准隔离性) -
confirm-确认执行业务
真正执行业务
不作任何业务检查
只使用Try阶段预留的业务资源
Confirm操作必须保证幂等性 -
cancel-取消执行业务
释放Try阶段预留的业务资源
Cancel操作必须保证幂等性
3、参考文档:
1、《终于有人把“TCC分布式事务”实现原理讲明白了!》
2、《分布式事务概述》
3、 《pageShardingSphere官方文档-分布式事务》
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/68747.html