分布式事务框架Seata及EasyTransaction架构的比对思考

本文将会对比Seata与EasyTransaction两个分布式事务的一些高层设计,以供大家选型参考。

Seata的概述

Seata(曾用名Fescar,开源版本GTS)是阿里的开源分布式事务框架,其RoadMap中指出了其希望与社区合作重新构建出一个全面的分布式事务框架。

关于Seata的相关介绍可以看这里,本文不再赘述。虽然其后续路线有所调整,但整体适用。

https://github.com/seata/seata/wiki/%E6%A6%82%E8%A7%88

学习了解Seata后我们可以比对着了解EasyTransaction的架构设计。

EasyTransaction概述

EasyTransaction(后简称ET)的目标也是构建出一个全面分布式事务解决方案,到目前为止其包含TCC,自动补偿(Seata AT),手动补偿,可靠事务消息、Saga事务等等多种形态。

下面将就两个框架在设计上的差异进行分析

核心差异图示

借用Seata的一张图:
分布式事务框架Seata及EasyTransaction架构的比对思考_第1张图片
与Seata不同,EasyTransaction对应的图如下:
分布式事务框架Seata及EasyTransaction架构的比对思考_第2张图片

TC差异

Seata:

  • 有独立部署的集中式TC
    • RM、TM与TC的交互通过RPC进行
  • TC中可以看到每个具体的事务分支,统一协调所有事务分支的提交及回滚

EasyTransaction:

  • TC是业务服务进程中的一个模块,并没有独立出来,且存在子事务的服务实例都会调用起TC模块
    • 如ServiceA,B,C都有TC,但ServiceD,E没有
    • 这里的有无指代的是这一次事务里TC的功能有没有被触发
    • TC与TM,RM的交互在进程内进行
  • 每个TC只能协调其直接子事务
    • 如ServiceA的TC只知道ServiceB及ServiceE的子事务
    • 但ServiceB知道还有ServiceC的子事务,因此可以递归协调
    • 每个服务实例发起的全局事务,服务实例自身会先尝试一次自协调(大多数都能成功),若自协调失败,则由一个服务实例兜底处理事务协调

Seata有集中式的TC,这样其可以 更容易 实现对分布式事务的监管控,如关于APM、Metrics、统一限流 等等功能。

但在EasyTransaction中的TC形式可以节约TC网络交互时间,在上述Seata的业务图中,ET的形式在两阶段提交中的第一阶段能节约6次 网络来回时间 及 正反序列化时间。

[(registerBranch以及reportBranch)* n个调用层级]

在两阶段提交的第二阶段中,统一提交或者回滚过程中,Seata的形式则是比EasyTransaction快,因为其不需要层级传递下去。视调用层级N的区别,ET形态的第二阶段会比Seata慢 n-1 个网络来回及正反序列化的的时间。

[ (commit或者rollback) * (n-1)个调用层级] 

至于 由于数据分散性等等原因APM、Metrics、统一限流 等等功能在ET形式如何实现 的这个问题,我们可以参考普通的RPC是怎么做的,将其纳入统一的RPC管理即可,只是统一管控的力度没有集中式的强大。

同时分散型的TC能 更容易 达到更高级别的可用性,其无需保证TC是否存活,业务服务在则TC在。分散的特征也让压力能在正常业务情况下,能均匀分散到不同的业务实例当中。

TM差异

Seata:

  • 独立于Spring/JTA的TransactionManager单独创建了另外一套TransactionManager
  • TransactionManager在一个全局事务里只有一个

EasyTransaction:

  • 扩展Spring的PlatformTransactionManager(后称PTM)的功能,使其可以管控分布式事务
  • 在每个事务分支里都有PTM(Spring原生的事务),但存在子事务的PTM将会挂载扩展分布式事务相关处理以及启动TC模块功能

Seata单独抽象了一套TM,其好处是自由可控,并可以不依赖于任何框架。

ET其TM依赖于Spring的PTM的话,Spring这个框架就变成了使用ET的必选项。但相对的好处就是,所有作用于这个PTM的设施都可以作用于EasyTransaction。

例如Spring的RollbackFor,Transactional,Suspend注解,XML事务切面配置等等都可以直接为EasyTransaction所用。因为ET仅仅只是扩展,因此这些功能都能兼容。甚至于我们要引入JTA,EasyTransaction也能兼容,因为PTM自身就有JTA的实现。

RM差异

Seata:

  • 所有参与到全局事务的RM都是平等的存在

EasyTransaction

  • 存在主控RM(发起方RM、发起方事务),从事务RM的区别

Seata全局事务都是平等的存在,整体逻辑上有简单统一的美,但因此其所有的RM都必须能接受两阶段的管控。

但在常规的业务模式中,全局事务开始者(Seata里带TM的那个)的事务,基本都可以在一阶段内获知全局事务应该回滚或者提交,但由于Seata RM都平等的模式,发起方RM必要要用AT模式(记录回滚数据),或者编写TCC的提交回滚方法,这里有一些额外的性能损耗

ET模式里存在事务发起方RM的设定,其只要事务发起方的事务提交成功则全局事务(最终)提交,发起方事务提交失败则全局事务(最终)回滚,因此其事务发起方无需兼容两阶段提交的协议,节约了相关的性能成本。

自动补偿实现差异

Seata:

  • 全局锁通过TC保存并实现

EasyTransaction:

  • 全局锁通过本地业务数据库保存

Seata通过TC保存全局记录锁引入了更多的复杂度,但其能自由控制锁的实现,能针对场景实现出效率更高的锁。

EasyTransction改造Seata的自动补偿功能,将原有的远程TC依赖改造成了EasyTransaction的分布式TC,并将全局锁实现改造到业务DB中。自动补偿的整体实现复杂度降低了,但性能可能有所下降(未经测试)。

不过Seata相关的实现也在进行中

RPC接口

Seata

  • 初期Seata试图维持其核心功能简洁,不涉及任何业务层次RPC的内容
    • 后面整合蚂蚁的TCC后框架核心代码开始出现RPC相关内容
  • 暴露给用户的是RPC框架原生的接口
  • 接口入参出参形式较为自由

EasyTransaction

  • RPC是EasyTransaction的一部分,其可更改替换
  • 直接暴露给用户使用的并非RPC框架,而是ET的相关接口,RPC仅作为底层通讯的支持
  • 接口入参出参形式有限制

EasyTransaction没有采用常规的做法,而是用自己的接口替代原RPC接口的一个原因是这样做能对整个事务过程能 更容易 地把控,其直接与业务交互,知道这一次调用的结果需要马上返回还是可以稍后返回,知道这一次调用是重试还是业务主动触发的,可以通过sdk主动设置RPC框架不进行重试,主动设置使其进行黏性会话以提高效率而不用用户额外单独配置

同时因为RPC是ET的一部分,因此幂等、cancel悬挂等等繁琐重复的问题,能更容易地通过框架自动支持(已经实现),但如果Seata坚持目前轻量级做法的话,将来在实现相关功能时可能会更困难。

当然对业务暴露了ET的接口也算是一种耦合的增强。

动态配置、服务发现、APM等

Seata

  • 通过主动配置对接

EasyTransaction

  • 利用Spring等现有设施对接

ET利用Spring现有的配置接口进行配置,因此只要相关配置中心对接了Spring,EasyTransaction就能使用。但Seata为了减少对Spring的依赖,因此相关对接需要单独进行。

ET的TC整合到业务服务中,因此TC相关的服务发现只要利用业务自身的服务发现就能完成。而Seata的TC单独部署,因此需要一定的适配工作。

跟上面的原因类似,EasyTransaction的APM等操作只需借用已经整合到RPC框架的APM即可,而Seata需要一定的适配工作

总结

Seata在短短几个月内能积累近万Star除了阿里的技术号召力外,当然还有另外一个原因是分布式事务领域如此普遍且重要,但缺少一个能让小白都能放心无脑使用权威的实现,无疑Seata在如此热烈的社区支持下很有希望能成为这么一个实现。

但在Seata真正成为这个权威实现前,我觉得大家也可以抽空了解下EasyTransaction这个目前功能更为强大、代码更为稳定、已上过生产的实现~

当然以上内容很多都带个人主观偏见,希望各位能补充各种看法,兼听则明!

欢迎关注个人公众号,多年金融码农,曾任某商业银行信用卡中心架构师、某创业公司架构组成员,现为某厂T3.2码农。

分布式事务框架Seata及EasyTransaction架构的比对思考_第3张图片

你可能感兴趣的:(分布式事务框架Seata及EasyTransaction架构的比对思考)