偶然间看到阿里开源的分布式事务中间件,期待有投入到生产阶段的栗子。从蓝图上看出目前有支持dubbo的解决方案,后续0.5.x版本会推出支持spring cloud的方案。 下面看官方正文,喜欢的能够去官方Github上瞧瞧看看。html
Fescar 是 阿里巴巴 开源的 分布式事务中间件,以 高效 而且对业务 0 侵入 的方式,解决 微服务 场景下面临的分布式事务问题。git
首先,设想一个传统的单体应用(Monolithic App),经过 3 个 Module,在同一个数据源上更新数据来完成一项业务。github
很天然的,整个业务过程的数据一致性由本地事务来保证。spring
随着业务需求和架构的变化,单体应用被拆分为微服务:原来的 3 个 Module 被拆分为 3 个独立的服务,分别使用独立的数据源(Pattern: Database per service)。业务过程将由 3 个服务的调用来完成。数据库
此时,每个服务内部的数据一致性仍有本地事务来保证。而整个业务层面的全局数据一致性要如何保障呢?这就是微服务架构下面临的,典型的分布式事务需求:咱们须要一个分布式事务的解决方案保障业务全局的数据一致性。服务器
阿里是国内最先一批进行应用分布式(微服务化)改造的企业,因此很早就遇到微服务架构下的分布式事务问题。架构
2014 年,阿里中间件团队发布 TXC(Taobao Transaction Constructor),为集团内应用提供分布式事务服务。并发
2016 年,TXC 通过产品化改造,以 **GTS(Global Transaction Service)**的身份登录阿里云,成为当时业界惟一一款云上分布式事务产品,在阿云里的公有云、专有云解决方案中,开始服务于众多外部客户。框架
2019 年起,基于 TXC 和 GTS 的技术积累,阿里中间件团队发起了开源项目 Fescar(Fast & EaSy Commit And Rollback, FESCAR),和社区一块儿建设这个分布式事务解决方案。异步
TXC/GTS/Fescar 一脉相承,为解决微服务架构下的分布式事务问题交出了一份不同凡响的答卷。
高速增加的互联网时代,快速试错 的能力对业务来讲是相当重要的:
基于这两点,咱们设计之初的最重要的考量就在于:
既有的分布式事务解决方案按照对业务侵入性分为两类,即:对业务无侵入的和对业务有侵入的。
既有的主流分布式事务解决方案中,对业务无侵入的只有基于 XA 的方案,但应用 XA 方案存在 3 个方面的问题:
实际上,最初分布式事务只有 XA 这个惟一方案。XA 是完备的,但在实践过程当中,因为种种缘由(包含但不限于上面提到的 3 点)每每不得不放弃,转而从业务层面着手来解决分布式事务问题。好比:
都属于这一类。这些方案的具体机制在这里不作展开,网上这方面的论述文章很是多。总之,这些方案都要求在应用的业务层面把分布式事务技术约束考虑到设计中,一般每个服务都须要设计实现正向和反向的幂等接口。这样的设计约束,每每会致使很高的研发和维护成本。
不能否认,侵入业务的分布式事务方案都通过大量实践验证,能有效解决问题,在各行种业的业务应用系统中起着重要做用。但回到原点来思考,这些方案的采用实际上都是 迫于无奈。设想,若是基于 XA 的方案可以不那么 重,而且能保证业务的性能需求,相信不会有人愿意把分布式事务问题拿到业务层面来解决。
一个理想的分布式事务解决方案应该:像使用 本地事务 同样简单,业务逻辑只关注业务层面的需求,不须要考虑事务机制上的约束。
咱们要设计一个对业务无侵入的方案,因此从业务无侵入的 XA 方案来思考:
是否能够在 XA 的基础上演进,解决掉 XA 方案面临的问题呢?
首先,很天然的,咱们能够把一个分布式事务理解成一个包含了若干 分支事务 的 全局事务。全局事务 的职责是协调其下管辖的 分支事务 达成一致,要么一块儿成功提交,要么一块儿失败回滚。此外,一般 分支事务 自己就是一个知足 ACID 的 本地事务。这是咱们对分布式事务结构的基本认识,与 XA 是一致的。
其次,与 XA 的模型相似,咱们定义 3 个组件来协议分布式事务的处理过程。
一个典型的分布式事务过程:
至此,Fescar 的协议机制整体上看与 XA 是一致的。
XA 方案的 RM 其实是在数据库层,RM 本质上就是数据库自身(经过提供支持 XA 的驱动程序来供应用使用)。
而 Fescar 的 RM 是以二方包的形式做为中间件层部署在应用程序这一侧的,不依赖与数据库自己对协议的支持,固然也不须要数据库支持 XA 协议。这点对于微服务化的架构来讲是很是重要的:应用层不须要为本地事务和分布式事务两类不一样场景来适配两套不一样的数据库驱动。
这个设计,剥离了分布式事务方案对数据库在 协议支持 上的要求。
先来看一下 XA 的 2PC 过程。
不管 Phase2 的决议是 commit 仍是 rollback,事务性资源的锁都要保持到 Phase2 完成才释放。
设想一个正常运行的业务,大几率是 90% 以上的事务最终应该是成功提交的,咱们是否能够在 Phase1 就将本地事务提交呢?这样 90% 以上的状况下,能够省去 Phase2 持锁的时间,总体提升效率。
这个设计,在绝大多数场景减小了事务持锁时间,从而提升了事务的并发度。
固然,你确定会问:Phase1 即提交的状况下,Phase2 如何回滚呢?
首先,应用须要使用 Fescar 的 JDBC 数据源代理,也就是 Fescar 的 RM。
Phase1:
Fescar 的 JDBC 数据源代理经过对业务 SQL 的解析,把业务数据在更新先后的数据镜像组织成回滚日志,利用 本地事务 的 ACID 特性,将业务数据的更新和回滚日志的写入在同一个 本地事务 中提交。
这样,能够保证:任何提交的业务数据的更新必定有相应的回滚日志存在。
基于这样的机制,分支的本地事务即可以在全局事务的 Phase1 提交,立刻释放本地事务锁定的资源。
Phase2:
XID 是一个全局事务的惟一标识,事务传播机制要作的就是把 XID 在服务调用链路中传递下去,并绑定到服务的事务上下文中,这样,服务链路中的数据库更新操做,就都会向该 XID 表明的全局事务注册分支,归入同一个全局事务的管辖。
基于这个机制,Fescar 是能够支持任何微服务 RPC 框架的。只要在特定框架中找到能够透明传播 XID 的机制便可,好比,Dubbo 的 Filter + RpcContext。
对应到 Java EE 规范和 Spring 定义的事务传播属性,Fescar 的支持以下:
全局事务的隔离性是创建在分支事务的本地隔离级别基础之上的。
在数据库本地隔离级别 读已提交 或以上的前提下,Fescar 设计了由事务协调器维护的 全局写排他锁,来保证事务间的 写隔离,将全局事务默认定义在 读未提交 的隔离级别上。
咱们对隔离级别的共识是:绝大部分应用在 读已提交 的隔离级别下工做是没有问题的。而实际上,这当中又有绝大多数的应用场景,实际上工做在 读未提交 的隔离级别下一样没有问题。
在极端场景下,应用若是须要达到全局的 读已提交,Fescar 也提供了相应的机制来达到目的。默认,Fescar 是工做在 读无提交 的隔离级别下,保证绝大多数场景的高效性。
事务的 ACID 属性在 Fescar 中的体现是一个比较复杂的话题,咱们会有专门的文章来深刻分析,这里不作进一步展开。
前文所述的 Fescar 的核心原理中有一个 重要前提:分支事务中涉及的资源,必须 是支持 ACID 事务的 关系型数据库。分支的提交和回滚机制,都依赖于本地事务的保障。因此,若是应用使用的数据库是不支持事务的,或根本不是关系型数据库,就不适用。
另外,目前 Fescar 的实现还存在一些局限,好比:事务隔离级别最高支持到 读已提交 的水平,SQL 的解析还不能涵盖所有的语法等。
为了覆盖 Fescar 原生机制暂时不能支持应用场景,咱们定义了另一种工做模式。
上面介绍的 Fescar 原生工做模式称为 AT(Automatic Transaction)模式,这种模式是对业务无侵入的。与之相应的另一种工做模式称为 MT(Manual Transaction)模式,这种模式下,分支事务须要应用本身来定义业务自己及提交和回滚的逻辑。
做为全局事务一部分的分支事务,除自己的业务逻辑外,都包含 4 个与协调器交互的行为:
业务逻辑不须要关注事务机制,分支与全局事务的交互过程自动进行。
业务逻辑须要被分解为 Prepare/Commit/Rollback 3 部分,造成一个 MT 分支,加入全局事务。
MT 模式一方面是 AT 模式的补充。另外,更重要的价值在于,经过 MT 模式能够把众多非事务性资源归入全局事务的管理中。
由于 AT 和 MT 模式的分支从根本上行为模式是一致的,因此能够彻底兼容,即,一个全局事务中,能够同时存在 AT 和 MT 的分支。这样就能够达到全面覆盖业务场景的目的:AT 模式能够支持的,使用 AT 模式;AT 模式暂时支持不了的,用 MT 模式来替代。另外,天然的,MT 模式管理的非事务性资源也能够和支持事务的关系型数据库资源一块儿,归入同一个分布式事务的管理中。
回到咱们设计的初衷:一个理想的分布式事务解决方案是不该该侵入业务的。MT 模式是在 AT 模式暂时不能彻底覆盖全部场景的状况下,一个比较天然的补充方案。咱们但愿经过 AT 模式的不断演进加强,逐步扩大所支持的场景,MT 模式逐步收敛。将来,咱们会归入对 XA 的原生支持,用 XA 这种无侵入的方式来覆盖 AT 模式没法触达的场景。
事务上下文在微服务间的传播须要根据微服务框架自己的机制,订制最优的,对应用层透明的解决方案。有兴趣在这方面共建的开发者能够参考内置的对 Dubbo 的支持方案,来实现对其余微服务框架的支持。
由于 AT 涉及 SQL 的解析,因此在不一样类型的数据库上工做,会有一些特定的适配。有兴趣在这方面共建的开发者能够参考内置的对 MySQL 的支持方案,来实现对其余数据库的支持。
支持接入不一样的配置和服务注册发现解决方案。好比:Nacos、Eureka、ZooKeeper 等。
MT 模式的一个重要做用就是,能够把非关系型数据库的资源,经过 MT 模式分支的包装,归入到全局事务的管辖中来。好比,Redis、HBase、RocketMQ 的事务消息等。有兴趣在这方面共建的开发者能够在这里贡献一系列相关生态的适配方案。
针对不一样场景,支持不一样的方式做为事务协调器 Server 端的高可用方案。好比,针对事务状态的持久化,能够是基于文件的实现方案,也能够是基于数据库的实现方案;集群间的状态同步,能够是基于 RPC 通讯的方案,也能够是基于高可用 KV 存储的方案。
绿色 部分是已经开源发布出来的,黄色 部分是将在后续版本中由阿里发布出来的,蓝色 部分是咱们和社区共建生态部分:
固然,项目迭代演进的过程,咱们最重视的是社区的声音,路线图会和社区充分交流及时进行调整。