10、分布式事务-Seata-AT模式-上

章节归属

分布式事务系列

1、背景

伴随着高性能的分布式系统演进,我们必然会经历 通过横向扩展节点 提高非热点数据的并发性能;而横向扩展节点实际是如下2方面的扩展变化:

  1. 扩展功能节点(对应应用的微服务化改造)
  2. 扩展数据节点(对应增加数据分片)

这些变化自然就引发 原来调用一个服务的一个接口就完成的功能,现在需要协同调用多个服务的多个接口才能完成。相信我们都遇到过因网络、机器、程序等不可靠,引发的数据一致性的问题。而数据的一致性与系统的可扩展性和高可用同样重要 是【基础IT架构】支撑业务高质量转型升级的重点也是难点。从蚂蚁金服的分布事务产品十几年的Roadmap可以看出其在数据一致性方面的坚持和不易(如今能快速使用他们的积累,幸甚至哉!),如下图所示:

image.png

从官宣得知,蚂蚁金服从微服务演进开始至今,大量的应用采用了TCC事务模型,2017年推出了FMT模式,类比即Seata中的AT模式。

2、起源

既然10年时间都是TCC模式,为什么会推出FMT(AT)模式呢,并且Seata官方也首推AT模式,注意AT是 Auto Transaction 的缩写,这个话题我觉得可以借助汽车从手动挡到自动挡的演进来讨论,早期全是自动挡汽车,但2021年统计显示自动挡车占比超过80%,为什么会这样呢:

  1. 自动档汽车比手动档汽车更容易操作
    自动档汽车可以自动匹配档位与速度,而手动档汽车则需要根据行驶速度,手动实现档位的转换。因此,自动档汽车更容易操作,更方便驾驶,尤其是对于缺少驾车经验的司机而言,自动档汽车是非常好的选择。
  2. 自动档汽车驾车舒适度更高
    自动档汽车不用进行手动换挡,不需要手和脚的密切配合。自动档汽车在驾驶时可以不用一直进行换档位,只需掌控踩油门的深浅,就可以轻松实现速度的转换,因此,很大程度上可以提高驾车舒适度。
  3. 自动档汽车安全系数更高
    对于新手来讲,让驾驶者专注于驾驶,避免额外的操控,做的少就错的少,错的少自然就降低事故率。

若将诞生于早期的TCC分布式事务模式类比成手动挡驾驶模式,那么Seata-AT模式就是当下主流的自动挡驾驶模式,正如有了自动变速箱后,驾驶者不需要知晓离合器、档位的存在,不用关注离合器、档位和油门三者之间那微妙协作;开发着不需要再去关心提供TCC三个方法,并掌控他们之间的协作;这些繁琐且难度高的事项由框架层托管,开发者只关注如何编写SQL来实现业务逻辑即可。

3、核心思想

Seata AT 模式 是基于数据源代理实现的,是增强型2pc模式;其核心思想就是由框架托管分布式事务:通过代理DataSource中的Connection,拦截SQL执行,改变其原执行逻辑,由代理引入额外的机制,加入额外的逻辑完成分布式事务。

4、角色和职责

4.1、基于JDBC驱动操作DB,提供服务

跟正常写业务服务没有区别。

4.2、角色

Seata-AT模式的实现中有3个重要角色

TC (Transaction Coordinator) - 事务协调者

维护全局和分支事务的状态,驱动全局事务提交或回滚。

TM (Transaction Manager) - 事务管理器(发起方)

定义全局事务的范围:开始全局事务、提交或回滚全局事务。

RM (Resource Manager) - 资源管理器(参与者)

提供TCC服务,与TC交谈以注册分支事务和报告分支事务的状态,并驱动分支事务提交或回滚。

4.3、二阶段的职责分工

AT 模式对业务无任何侵入,其一阶段和二阶段的提交\回滚均由 Seata 框架自动生成,用户只需编写“业务 SQL”,便能轻松接入分布式事务。

image.png
4.3.1 第一阶段:

如下图所示,Seata 会拦截“业务 SQL”,首先解析 SQL 语义,找到“业务 SQL”要更新的业务数据,在业务数据被更新前,将其保存成“before image”,然后执行“业务 SQL”更新业务数据,在业务数据更新之后,再将其保存成“after image”,最后生成行锁。以上操作全部在一个本地数据库事务内完成,这样保证了一阶段操作的原子性。

image.png

第一阶段总结来说即是:业务sql和记录回滚日志的sql在同一个本地事务中提交,提交后即释放本地连接资源。

4.3.2. 第二阶段
4.3.2.1 二阶段-提交

因为“业务 SQL”在一阶段已经提交至数据库, 所以 Seata 框架只需将一阶段保存的快照数据和行锁删掉,完成数据清理即可。


image.png
4.3.2.2 二阶段-回滚

Seata 需要回滚一阶段已经执行的“业务 SQL”,还原业务数据。回滚方式便是用“before image”还原业务数据;但在还原前要首先要校验脏写,对比“数据库当前业务数据”和 “after image”,如果两份数据完全一致就说明没有脏写,可以还原业务数据,如果不一致就说明有脏写,出现脏写就需要转人工处理。


image.png

第二阶段总结来说即是:TC向RM发起提交或回滚;提交的话通过异步进行回滚日志的自动清理,事务得以马上结束;回滚的话,通过一阶段的回滚日志,自动生成并执行补偿回滚的数据操作。

5、工作原理

5.1、整体架构

Seata-AT模式整体架构如下图所示:

image.png
5.2、核心流程
5.2.1、第一阶段
image.png

以一个原本有100块的账户扣掉10块钱为例:update account seg balance=balance-10 WHERE uId='001'

  1. 解析SQL:解析得到操作类型、表和条件,这里SQL操作类型是update,表是account,条件是uid='001' 信息
  2. 生成before image:从 account表中检索uId='001'的账户在执行update之前的余额,得到了100,即before image的结果集,作为回滚时使用的数据
  3. 执行业务SQL:update account set balance=balance-10 where uId='001'
  4. 生成after image:从 account表中检索uId='001'的账户的在执行update之后的余额,得到了90,即after image的结果集,作为回滚时用于比对判断是否有脏写的依据
  5. 记录undolog:将前后镜像组合,以 json格式压缩一下存到 UNDO_LOG 表中
  6. 提交前,RM向TC注册分支:这里会申请 account 表中主键值等于 '001' 的记录的全局锁,锁的粒度是:服务+表+记录ID
  7. 提交本地事务:将业务数据的更新和undolog的记录 一并提交
  8. 将本地事务提交的结果上报给 TC
5.2.2、第二阶段-提交
image.png
  1. TM 向 TC 发起全局事务提交
  2. TC 向 各RM 发起分支提交(传递XID)
  3. RM 接收到请求后放入一个异步任务的队列中,并立即返回TC提交成功
  4. 异步任务批量地删除相应 undolog
5.2.3、第二阶段-回滚
image.png
  1. 收到 TC 的分支回滚请求,开启一个本地事务
  2. 通过 XID 和 Branch ID 找到相应的 undolog
  3. 校验脏写:后镜像与当前数据库数据比较,如有不同则说明已被当前全局事务外的动作做了修改,此时需根据配置策略来处理
  4. 还原数据:根据前后镜像,生成逆向SQL并“回滚”(相当于重新写入一次)
  5. 删除undolog
  6. 提交本地事务,并把本地事务的执行结果(即分支事务回滚的结果)上报给 TC
5.3、注意事项
  1. 空回滚、 防悬挂、 幂等控制
    在TCC模式下,需要考虑 空回滚、 防悬挂、 幂等控制的情况。但是在AT模式下,不需要有业务层去关注这些问题,因为框架可以通过AT模式中生成的前后镜像,自动处理以上问题。
  2. 数据隔离
    本地事务的支持是seata实现at模式的必要条件,在数据库本地事务隔离级别 读已提交(Read Committed) 或以上的基础上,Seata(AT 模式)的默认全局隔离级别是 读未提交(Read Uncommitted) ,通过 SELECT FOR UPDATE 语句实现读已提交 。

6、总结

跟TCC事务模式对比AT自动事务模式能带来这些好处:

  1. 难度低
    AT模式 对于缺少分布式事务经验的开发者来说,开发者仅按照传统开发模式,通过简单的注解就可委托框架层补充实现整个分布式事务,甚至不需要了解分布式事务的原理。
  2. 效率高
    AT模式,开发者专注于业务sql,只需要加注解就可实现分布式事务,而无需处理如TCC模式下的服务逻辑需拆分为try 、confirm和cancel三个部分;因此,很大程度上可以提高开发效率。
  3. 更安全
    拿TCC事务模型来说,要求开发者将服务拆分为try 、confirm和cancel三个部分,同时还要求开发者自身有缜密的设计和严谨的代码来控制事务安全,应对空回滚、幂等、悬挂等问题,并兼顾性能 ;而开发者对分布式事务的掌握程度不尽相同,自然实现的质量也很难保证。

缺点:

  1. 性能损耗
    前后两次查询,以及与TC的RPC通信,以及undo_log的写入,会增加更多的开销。
  2. 热点数据
    全局锁虽然是行锁,但对热点数据的读写依然不友好。

Seata AT和XA模式联系和区别

你可能感兴趣的:(10、分布式事务-Seata-AT模式-上)