美文网首页
10、分布式事务-Seata-AT模式-上

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

作者: rock_fish | 来源:发表于2022-08-17 00:51 被阅读0次

章节归属

分布式事务系列

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模式-上

    章节归属 分布式事务系列[https://www.jianshu.com/p/aad42cdafef4] 1、背景...

  • Seata-AT模式

    Seata-AT模式 概念:AT模式是一种无侵入的分布式事务解决方案,在 AT 模式下,用户只需关注自己的“业务 ...

  • SprinrBoot整合Seata使用AT模式解决多数据源分布式

    SprinrBoot整合Seata使用AT模式解决多数据源分布式事务 分布式事务场景: 1.应用中使用多数据源,跨...

  • seata-golang 接入指南

    seata-golang 是一个分布式事务框架,实现了 AT 模式和 TCC 模式,AT 模式相较 TCC 模式对...

  • 分布式事务 | 使用 dotnetcore/CAP 的本地消息表

    本地消息表模式 本地消息表模式,其作为柔性事务的一种,核心是将一个分布式事务拆分为多个本地事务,事务之间通过事件消...

  • 分布式事务

    分布式事务 强一致性事务 XA 柔性事务 BASE2.1 不使用事务,业务侧补偿 SAGA模式2.2 使用柔性事务...

  • 分布式事务

    分布式事务 是什么 分布式事务就是一次大的事务操作由不同的小操作组成,这些小操作分布在不同的服务器上 分布式事务需...

  • Seate

    Seata是阿里开源的一个分布式事务框架。Seata主要有两种分布式事务实现方案,AT及TCC AT模式主要关注多...

  • 一、分布式事务的应用场景

    现在提起分布式事务中的“事务”,和传统的数据库事务中的“事务”严格意义上已经不是完全等同的了。 设计一个分布式事务...

  • 分布式事务与分布式锁

    一、分布式事务 什么事分布式事务 分布式事务就是指事务的资源分别位于不同的分布式系统的不同节点之上的事务。 分布式...

网友评论

      本文标题:10、分布式事务-Seata-AT模式-上

      本文链接:https://www.haomeiwen.com/subject/miluirtx.html