|
一、背景随着业务发展,单体系统逐渐无法满足业务的需求,分布式架构逐渐成为大型互联网平台首选。伴随而来的问题是,本地事务方案已经无法满足,分布式事务相关规范和框架应运而生。在这种情况下,大型厂商根据分布式事务实现规范,实现了不同的分布式框架,以简化业务开发者处理分布式事务相关工作,让开发者专注于核心业务开发。Seata就是这么一个分布式事务处理框架,Seata是由阿里开源,前身为Fescar,经过品牌升级变身Seata。二、分布式事务规范1.分布式事务相关概念事务: 一个程序执行单元,是用户定义的一组操作序列,需要满足ACID属性。本地事务:事务由本地资源管理器管理。分布式事务:事务的操作位于不同的节点。分支事务:在分布式事务中,由资源管理器管理的本地事务。全局事务:一次性操作多个资源管理器完成的事务,由一组分支事务组成。2. 分布式事务实现规范对于本地事务,可以借助DBMS系统来实现事务的管理,但是对于分布式事务,它就无能为力了。对于分布式事务,目前主要有2种思路:XA协议的强一致规范以及柔性事务的最终一致性规范。2.1 XAXA是基于2阶段提交协议设计的接口标准,实现了XA规范的资源管理器就可以参与XA全局事务。应用承担事务管理器TM工作,数据库承担资源管理器RM工作,TM生成全局事务id,控制RM的提交和回滚。2.2 柔性事务的最终一致性该规范主要有3种实现方式,TCC、MQ事务消息、本地消息表。(还存在其他一些不常用实现方式如Saga)。TCC:try/confirm/cancel,在try阶段锁定资源,confirm阶段进行提交,资源锁定失败执行cancel阶段释放资源。MQ事务消息:前提消息系统需要支持事务如RocketMQ,在本地事务执行前,发送事务消息prepare,本地事务执行成功,发送事务消息commit,实现分布式事务最终一致性。如果事务消息commit失败,RocketMQ会回查消息发送者确保消息正常提交,如果步骤5执行失败,进行重试,达到最终一致性。本地消息表:跟MQ事务消息类似,区别在于MQ不支持事务消息,需要借助本地数据库的事务管理能力。在步骤1中将需要发送的消息和本地事务一起提交到DB,借助DB的事务管理确保消息持久化。步骤2应用通过本地消息表扫描,重试发送,确保消息可以发送成功。三、Seata 架构1.系统组成Seata有三个核心组件:Transaction Coordinator(TC,事务协调器)维护全局事务和分支事务的状态,驱动全局事务提交或回滚。Transaction Manager(TM,事务管理器)定义全局事务的范围,开始事务、提交事务、回滚事务。Resource Manager(RM,资源管理器):管理分支事务上的资源,向TC注册分支事务,汇报分支事务状态,驱动分支事务的提交或回滚。三个组件相互协作,TC 以 Server 形式独立部署,TM和RM集成在应用中启动,其整体交互如下:2.工作模式Seata 支持四种工作模式:2.1 AT(Auto Transaction)AT模式是Seata默认的工作模式。需要基于支持本地 ACID 事务的关系型数据库,Java 应用,通过 JDBC 访问数据库。2.1.1 整体机制该模式是XA协议的演变,XA协议是基于资源管理器实现,而AT并不是如此。AT的2个阶段分别是:一阶段:业务数据和回滚日志记录在同一个本地事务中提交,释放本地锁和连接资源。二阶段:提交异步化,非常快速地完成;回滚通过一阶段的回滚日志进行反向补偿。下图中,步骤1开启全局事务;步骤2注册分支事务,这里对应着一阶段;步骤3提交或者回滚分支事务,对应着二阶段。2.1.2 特点优点:对代码无侵入;并发度高,本地锁在一阶段就会释放;不需要数据库对XA协议的支持。缺点:只能用在支持ACID的关系型数据库;SQL解析还不能支持全部语法。2.2 TCC该模式工作分为三个阶段:prepare/commit/cancel。2.2.1 整体机制TM向TC申请全局事务XID,传播给各个子调用。子调用的所在TM向TC注册分支事务,并执行本地prepare,并向TC报告执行结果。TC根据各分支事务的执行结果确定二阶段是执行commit或rollback。2.2.2 特点优点:不依赖本地事务。缺点:回滚逻辑依赖手动编码;业务侵入性较大。2.3Saga 模式2.3.1 Saga 是什么?1987年普林斯顿大学的Hector Garcia-Molina和Kenneth Salem发表了一篇Paper Sagas,讲述的是如何处理long lived transaction(长活事务)。Saga是一个长活事务可被分解成可以交错运行的子事务集合。论文见这里。简单来说,Saga将一个长事务(T)分解成一系列Sub事务(Ti),每个Sub事务都有对应的补偿动作(Ci),用于撤销Ti事务产生的影响。Sub事务是直接提交到库,在出现异常时,逆向进行补偿。因此Saga事务的组成有2种:T1, T2, T3, ..., TnT1, T2, ..., Tj, Cj,..., C2, C1,其中0
|
|