“若干分布式事务框架设计”与“个人偏见”

本文来谈谈我对若干分布式事务框架的见解,只谈设计时致使没法轻易改变的硬伤(或者说个人偏见),其优势应该已表如今其文档中,再也不赘述。至于个人偏见能不能成为你的偏见,请自行思考核实,仅供你们选型时开拓思路使用。 git

靶子

如下我略有了解的框架将成为靶子:github

  • TransactionsEssentials(atomikos免费版)
  • tcc-transaction
  • ByteTCC
  • hmily
  • tx-lcn
  • GTS
  • EasyTransaction

TransactionsEssentials

其是atomikos公司的两阶段提交事务的免费版本,说到两阶段提交你们第一印象应该都是慢,第二印象应该就是很方便,编码少。数据库

但实际上有多慢呢?可能你们都不太肯定,我这里有一组数字供你们参考,相同业务场景,两个服务有数据协同需求:编程

  • 若两个服务在同一库中,单库事务可达600TPS+
  • 但Atomikos速度为40-70TPS

固然,这里没有给出具体的场景与配置,确实差值也有点大,我当时也是不太相信的。但我从多个不一样测试数据源得到的数据都较为相似,你们有空能够协助验证下,而后评论给下数据。安全

因此对于TransactionsEssentials这个框架,个人偏见就是,太慢。网络

tcc-transaction

这是一个在GITHUB上开源了好久的框架了,其STAR数量接近3K,其代码简洁易懂。但其有三个缺点:并发

  • 应用Crash时有概率致使持久化的事务状态不正确
  • 不支持框架幂

慢的缘由

  • 事务日志使用一个数据库的变长字段存储
  • 会屡次更新该字段
  • 该字段存储的内容不断变长,使其不能在磁盘中原地更新,致使页的分裂,或者致使该字段从页中移除,涉及大量IO

CRASH不一致的缘由

  • 其CRASH后纯粹依赖事务日志判断全局事务状态(Trying,Confirming,Canceling)
  • 然而该事务日志记录的事务状态是没法与业务数据库的事务状态保持强一致的(若能,则须要引入2PC等手段,是否是很矛盾)
  • 所以在Crash时致使事务日志状态不正确时,按照目前的设计是须要人工介入排查问题的

不支持框架幂等

这会致使业务开发工做量大大增长。mvc

ByteTCC

ByteTCC是一个兼容JTA规范的基于TCC机制的分布式事务管理器。框架

其实我的以为基JTA规范扩展的TCC实现并不是一个特别好的想法,其异步

  • 强制Spring的PlatformTransactionManager要支持JTA,须要用户修改原有的PlatformTransactionManager
  • 使用了ByteTCC自行实现的UserTransaction(JTA相关接口),并在里层整合"TCC"及“真JTA”的控制逻辑,这违反了编程里的开闭原则
    • 用自定义实现类替换掉了客户原有实现中可能更为可靠的JTA/JDBC事务,即单机事务的代码逻辑也被改了
    • 在JTA接口中整合“真JTA”及“TCC”的逻辑交错在整个实现中,没有很好地分离逻辑,不利于阅读,也不利于修改
    • 限制了使用其余的JTA实现

不知道你们有没有听懂我上面说了什么,其实就是说,若是让我来设计,我是尽可能不会对原有逻辑进行修改,而是对逻辑进行扩展,这样才能最大程度的程序的安全性,也能更好地与原有逻辑整合。

举个例子,EasyTransaction里就是基于扩展实现了各类功能,其能保证原有事务处理逻辑彻底不变,仅仅只是外挂了TCC、可靠消息等等的实现,同等状况下,其实现的理论风险会更小,而且EasyTransaction能无缝兼容JTA事务以及EasyTransaction内的各类事务,并协调一块儿工做,而ByteTCC则因为其实现形式,难以简单作到。

另一个方面是其代码变得过于复杂,至少对我来讲有理解难度,须要一些额外的知识支撑,不知道其余人的见解是怎样的。

同时关于幂等,ByteTCC只支持Confirm及Cancel操做的幂等,不过这比不少框架都要强了。

hmily

这个框架的主要描述是“高性能分布式事务tcc方案开源框架”,我的感受其之因此这么声称是由于“采用disruptor框架进行事务日志的异步读写,与RPC框架的性能毫无差异”。

这里有两个我的认为的硬伤(也许是偏见吧):

  • 异步写入事务日志就等于TCC是不可靠的
  • 持久化IO瓶颈才是一个分布式事务框架的主要瓶颈,其并不是Disruptor框架主要针对的CPU瓶颈

为何不可靠

就一个简单的问题吧,事务日志存储链接不上(网络断掉/掉电了),这时异步写入的日志放到内存了,而后远程的访问请求TRY发出去了,这个时候应用CRASH了。这就会致使TCC日志不完整,从而致使事务没法恢复。

有一些观点认为这些状况极其少见,不需处理,那咱们并发编程时volatile之类的同步手段还须要用么?

而且异常都是连锁的,它并非孤立出现的,咱们没法预判会出现什么异常状况,也有墨菲定律说,越担忧的事情越有可能发生,所以咱们对于这类状况必然是虽然咱们不能保证明现完美,可是咱们的理论至少要使完美的。

异步的Disruptor并不能解决矛盾的主要方面

咱们知道,CPU的速度会比持久化IO的速度高不少个数量级,所以,基本上涉及持久化时,IO必然才是主要优化的目标。

所以咱们作优化时,仿照KAFKA等,批量聚集数据,批量IO才是正确的解决之道。不作这个而去优化CPU性能这有点本末倒置,同时据我了解的多个测试结果中,hmily的性能都大幅不及EasyTransaction。

也不支持框架幂等

同上Tcc-transaction

tx-lcn

这个框架本质上是一个BestEffors 1PC的框架,是什么意思呢,也就是大多数状况下,只要应用不Crash就不会致使不一致。

这里带来什么矛盾呢?除非你不关心不一致,容许数据出错不修复,但一旦出现数据不一致必定要修复的状况的话,就要走人工补偿处理,或者调用相关的修复程序。

而人工补偿处理,实际上,也就至关于人肉写了一遍修复程序,并且人肉执行还没留下代码,下次出问题还要人工再分析处理一遍。

所以,结论很明显:

  • 对于容许数据不一致的数据来讲
    • 用BestEffors 1PC挺好的,性能高于2PC,代码量与2PC同样。
  • 可是对于数据出现不一致时,必须修复的状况
    • 咱们必需要写对应的修复程序
    • 这实际上跟TCC/补偿等工做量同样了
    • 为啥不切换到TCC/补偿等性能更加高的形式
    • 而且使用BestEffors1PC写的业务代码在出现数据异常时,并不能保证其后续的补偿是可执行的。
    • 举个例子,转帐,出现了给别人加钱了,可是本身没有扣钱的数据异常,此时两位客户就有可能立马把钱取出来用掉

tx-lcn这个框架是有适用场景的,可是我我的以为最好把相关的厉害关系放到险要位置,否则有巨多小白无脑就用了,而不知道其中的坑,我以为不太好。

GTS

这个框架的偏见嘛,主要就是脏读了。贴一段以前写过的文字。

GTS确实很赞,其核心原理是补偿。

但这个补偿作得很厉害,补偿操做由框架自动生成,无需业务干预,框架会记录修改前的记录值到上面的txc_undo_log里,若须要回滚,则拿出undo_log的记录覆盖回原有记录

同时这里存在一个事务隔离级别的问题,GTS的作法是默认脏读,那么就能够直接拿数据库记录展现(但我的以为应该能够不作脏读,直接拿undo_log里的记录作mvcc,只要undo_log记录不大,均可以加载到内存里)。

还有另一个问题是如何禁止其余事务对进行中的全局事务记录的更新,GTS的作法是须要接管APP中的数据源,这样就能够解析控制业务要执行的SQL,对于update操做(或者select for update),予以禁止或等待。

不过总体的作法至关于魔改数据库,将数据库的部分功能拉到了业务APP里进行,并修改了默认隔离级别(脏读,若是业务有用数据库记录乐观锁来控制并发的话,将会失效),还有就是,不经过GTS的定制数据源访问会访问修改到未提交数据

EasyTransaction

这个嘛,是我本身写的框架,上面出现的偏见,在我这里都不会有,这篇文章本质是个软文,哈哈,因此ET在我这没有偏见,但我汇总下ET的优势把:

  • 真正的高性能,对IO作了大量优化,多个独立三方公司横向评测分布式事务框架时,同等场景及同等可靠性保证下性能最佳(可自行验证测试)
  • 理论上只要外部组件不丢数据,在ET内部是不会出现事务不完整的状况(相对于上面一些框架,其原理就不可靠,运行出现异常能够说是必然的)
  • 支持框架幂等,业务程序程序再也不须要接管 幂等、调用时序错乱处理等繁琐重复逻辑(这个是一个繁琐重复的工做,貌似只有ET对本项进行了完整支持)
  • 基于扩展的实现,而非基于修改的实现,更易理解,风险更小,功能更强大
  • 支持多种事务形态(TCC,补偿,可靠消息,SAGAs等)混合使用,可按照最适合业务的选择最贴切的事务形态(这时ET建立之初的理念及特色,也是其余框架所不具备的特性)

总结

以上的偏见是不成熟的小想法,如有不正确,各位大佬尽管在评论区拍砖。同时本文仅供各位大佬选型时开拓思路,我认为的偏见不必定就是你的偏见,可能仅仅只是考虑角度、设计理念不同而已。

我的认为EasyTransaction的理念、设计、可靠性、性能等都不会比上面的框架差,但ET的STAR数量却不及上面的各个开源框架,我以为必定是ET有什么我本身没有察觉到的缺陷,请你们拍砖以促进本框架进步,能够直接评论,或者到GITHUB上提ISSUE,感谢你的改进建议!

https://github.com/QNJR-GROUP/EasyTransaction
相关文章
相关标签/搜索