半步多 玄玉的博客

分布式事务04之Seata-XA模式及Seata高可用

2020-08-08
玄玉

传统XA模式

XA 是数据库厂商实现的两阶段提交的一个强一致的协议(也就是对 2PC 规范的落地)

换句话说,XA 模式也就是基于事务资源(数据库)本身提供的 XA 规范和协议的支持

它的核心价值:

  • 从场景上看,满足全局一致性的需求
  • 从应用上看,保持与 AT 模式一样的无侵入
  • 从机制上看,适应分布式微服务架构的特点

XA 模式的优劣势:

  • 优势:
    1. 业务无侵入(无需业务逻辑参与)
    2. 数据库支持广泛(XA 协议被主流关系型数据库广泛支持,无需额外的适配即可使用)
    3. 多语言支持容易(对于 Seata 来说,改造时,其对 RM 要求较少,所以为不同语言开发 SDK 更容易)
    4. 传统基于 XA 事务的应用可以平滑的迁移到 Seata 平台
  • 劣势:
    1. 性能差
    2. 数据锁定:数据在整个事务处理过程结束前,都被锁定,读写都按隔离级别的定义约束起来
    3. 协议阻塞:XA prepare 后,分支事务进入阻塞阶段,收到 XA commit 或 XA rollback 前必须阻塞等待

关于性能,主要来自两方面:

  1. 事务协调过程增加单个事务 RT(RequestTime请求耗时),降低吞吐(时间都耗在等待全局事务处理完,整个请求才完)
  2. 并发事务数据的锁冲突

可能有人觉得我锁的都是我的记录,其它记录根本不影响别人用啊,我也不觉得它的性能衰减能有多严重啊

这虽然也有些道理,但要注意:在锁的过程中,数据库连接还没释放,还占用连接池里的一个连接

如果多来几个分布式事务,连接池里的连接都用光了,导致可能有的事务等的不是你的锁,等的是数据库连接

尽管如此,它的一致性保障还是非常好的,如果真正有必要用的话,也可以用

比如短事务:就一两个子事务的情况,可以马上把事务对齐,马上提交,那也 OK

SeataXA模式

该模式的前提是:需要支持 XA 事务的数据库,并且 Java 应用通过 JDBC 访问数据库

它分成以下两个阶段

  1. 执行阶段(Execute):XA start/XA end/XA prepare + 注册分支
  2. 完成阶段(Finish):XA commit/XA rollback

处理流程就非常简单了:

  1. TM 向 TC 开启全局事务
  2. 每个分支事务注册到 TC
  3. 各个 RM 中的分支事务自己去处理(执行SQL),也不用向 TC 上报事务状态了(因为分支事务根本就没提交)
  4. 最后 TC 再统一调用 commit 或 rollback 就行了

数据源代理

XA 模式 XAConnection,一般有两种方案:

  1. 要求开发者配置XADataSource(这时开发人员就需要显式的知道:系统接入 XA,并适当的去了解相关知识)
  2. 根据开发者的普通DataSource来创建(这时开发人员用的还是普通的DataSourcePool,做到了业务完全无感知)

第二种方案的好处是:开发者完全不必关心 XA 层面的任何问题,保持本地编程模型即可

只不过它也有局限:无法保证兼容的正确性

因为它是把原来的 connection 替换成了 XAConnection,相当于是自己重写了连接,自己去实现了 XA 驱动

其本质是在做数据库驱动程序要做的事情,等于是为数据库驱动程序补充功能

而不同厂商不同版本的数据库驱动实现机制是厂商私有的,开发者使用的驱动程序版本差异很可能造成机制的失效

这点在 Oracle 上体现非常明显。参见 Druid issue:https://github.com/alibaba/druid/issues/3707

并且第一种方案基于 XA 数据源进行代理的方式:其实业务上的改动并不大,是可以接受的

Seata高可用

TC有状态部署

如果把 TC 中的数据存到本地文件,那 TC 就变成有状态部署了。但若 TC 挂了,然后在另一台机器再部署一个 TC

那新 TC 是没有数据的,即无法异地恢复,除非把原 TC 的存储文件拿到新 TC 机器上,但如果原 TC 机器也挂了呢

这就是有状态部署的问题:不支持异地恢复(像 ShardingSphere 的分布式事务解决方案,它就不支持异地恢复)

TC无状态部署

TC 数据都放到一个公共存储里(比如数据库),这样TC就是无状态的了

就可以无限扩展 TC(分布式玩的就是扩展性),每次扩展后都会注册到注册中心,这就保证了高可用

一致性协议同步

还有一种方案,是把数据放到 TC 内部,但这就涉及到数据同步(考虑数据一致性协议,处理数据分块和数据路由等)

它的优点是可以存储非常多的数据(貌似是用 RocksDB 来存的),理论上是无限量的数据(支持不停的扩机器)

这里就略了:毕竟本身 TC 就没有多少数据,用不着搞这么麻烦,真到了业务量这么大的那天,估计做梦都乐醒了吧


相关文章

Content