社区编辑申请
注册/登录
事件驱动的分布式事务架构设计
开发 架构 新闻
在传统的软件架构中,应用逻辑是通过请求、过程驱动的。

一、什么是事件驱动架构

事件驱动架构是一种促进生产的 软件架构范式 。事件驱动架构在用微服务构建的现代应用中非常普遍,它用事件来触发、解耦服务之间的通信。事件可以是 状态的变更 ,比如将商品放入购物车;也可以是 某种标识 ,比如订单的发货通知。

在传统的软件架构中,应用逻辑是通过请求、过程驱动的。一个请求执行一段逻辑同步返回一个响应,在业务逻辑中,将要执行的代码按照过程顺序进行编排。

而事件驱动架构中,事件消费者会以 异步 的方式处理事件生产者产生的事件,原来过程当中的逻辑交给事件消费者去处理,解开服务之间的耦合,使应用的逻辑聚焦,应用的 职责单一 , 代码更加简洁 ,也能 提升系统的响应能力 。

二、分布式事务的事件驱动架构

在 2020 年,本文作者开源了 Go 语言的分布式事务框架 Seata-Golang。Seata-Golang 实现 AT 模式和 TCC 模式,这两种模式都是过程驱动。

到了 2022 年,随着对云原生技术的理解深入,从 Kubernetes Control-Loop 思想中获得灵感,全新设计了高性能、无侵入、事件驱动的 Go 语言分布式事务框架 hptx ,以及支持跨语言分布式事务、读写分离、分库分表的 Mesh 方案 DBPack 。这两款产品都能解决分布式事务问题, 前者只支持 Go 语言 , 后者支持任意编程语言 。他们采用了相同的事件驱动架构。下面进行详细的说明。

过程驱动

在 Seata 的设计中,事务发起者发起全局提交后,首先会判断该事务是否允许异步提交,如果允许,则直接返回提交成功,然后 由  ​AsyncCommittingSessionManager​ 来异步地通知每个分支事务提交,AT 事务默认允许异步提交。

如果不允许异步提交,事务协调者会依次通知全局事务参与者即每个分支事务提交,所有分支事务提交成功后,同步返回给事务发起者全局事务提交的结果,如上图。事务协调者通知事务参与者提交过程中发生了异常,会将该全局事务标记为  CommitRetrying​ 状态,将会有一个  RetryCommittingSessionManager 定时从持久存储中捞取标记的全局事务重试提交。

全局回滚的过程与上图类似,全局回滚时,AT 模式和 TCC 模式都是同步执行,依次通知每个分支事务回滚,然后再响应回滚结果给事务发起者。如果回滚失败,则将全局事务标记为 RollbackRetrying​ ,由  RetryRollbackingSessionManager 定时捞取标记的全局事务数据重试回滚。

Seata-Golang 的用户经常会问一个问题,事务协调者 TC Server 怎么做高可用?

Seata 包括 Seata-Golang 默认推荐使用 Mysql 数据库作为 TC 状态数据的持久化存储。TC Server 本身则是无状态应用,可以部署多个副本,但这里就存在一个问题:多个对等副本里的 

AsyncCommittingSessionManager​ 、 RetryCommittingSessionManager​ 、 RetryRollbackingSessionManager  都会从数据库去捞取对应的数据执行,会导致事务的提交、回滚重复执行,虽然 AT 模式天然做到幂等,TCC 模式由用户保证幂等,但总是存在一定的资源浪费,且不够优雅。

事件驱动

上图展示了 hptx 和 dbpack 的事务协调逻辑,事务发起者 AggregationSvc 发起全局事务提交、回滚,仅仅是修改 ETCD 中的数据状态,然后立即返回。订单服务和商品服务使用前缀  bs/${appid}​  Watch 存储在 ETCD 中的分支事务数据,当分支事务的数据发生过变更后,ETCD 马上推送一个变更事件给相应服务,订单服务和商品服务收到变更事件后,将数据加入  workqueue  去执行提交或回滚的逻辑。

AggregationSvc 提交、回滚时不会调用 OrderSvc、ProductSvc 的接口,整个过程通过 ETCD 解耦后异步执行。

事务分支提交或者回滚失败后,会重新进入到 workqueue​ 当中继续消费,直至提交、回滚成功,或回滚超时(AT 模式回滚操作涉及到全局锁的释放,需要设置超时时间,即  retry_dead_threshold )。

在这个架构中,已经没有中心化事务协调者 TC Server,用户只需要关心自身应用的高可用,如果应用多副本部署,hptx 和 dbpack 会通过 etcd 选主,只有选为 master 的副本才能 watch 自身产生的分支事务数据去做提交、回滚,避免了提交、回滚逻辑重复执行的问题。

集成 hptx,只需要依赖相应的 sdk,而不需要部署额外的 TC Server,但状态数据的存储由原来的 Mysql 换成了 ETCD。

三、新架构带来的好处

全新的、云原生的、事件驱动架构,更加简洁,性能更强。采用 hptx 的应用事务协调性能比 Seata-Golang 提升 1 倍,通过 dbpack 以 mesh 方式协调分布式事务性能比 seata-golang 提升了百分之 50。下面是一些测试数据:

环境

性能

seata-golang

2018 款 Mac book pro

每秒 18.54 笔事务

hptx

2018 款 Mac book pro

每秒 38.89 笔事务

dbpack

2018 款 Mac book pro

每秒 28.09 笔事务

hptx

阿里云 ecs ecs.sn1ne.xlarge (4 核 8G)

每秒 35.15 笔事务

hptx 是当前性能最强的云原生、无侵入分布式事务解决方案,选择其他内存型存储组件理论上可以得到更高的性能,但综合可靠性和性能,ETCD 是目前最好的选择。

四、结语

经过持续地在分布式事务领域的研究总结,使分布式事务框架不断进化,从最初的兼容 java seata 的 seata-golang v1 版本,到云原生的、无侵入的、基于 grpc 的 seata-golang v2 版本,到基于 ETCD watch 机制的、事件驱动的 hptx,再到跨语言的 dbpack,分布式事务一直在进化,能力也在进一步增强。

责任编辑:张燕妮 来源: GoCN
相关推荐

2022-06-18 23:03:05

Seata分布式事务

2022-06-14 11:15:09

代码驱动

2021-09-28 09:43:11

2022-06-10 10:39:44

2017-09-19 09:36:24

2019-10-21 08:51:41

分布式事务CAPAP

2017-07-26 15:08:05

大数据分布式事务

2010-07-05 15:48:44

SQL Server

2020-03-31 16:13:26

分布式事务方案TCC

2019-08-19 10:24:33

2022-01-26 13:46:40

2009-06-19 15:28:31

2021-12-23 09:00:00

架构微服务数据

2021-06-25 10:35:58

2020-03-31 08:05:23

2021-04-27 07:52:18

分布式事务系统

2021-06-28 10:03:44

2020-02-15 08:06:25

2021-11-23 23:39:19

2019-10-12 09:04:59

微服务架构CAP

同话题下的热门内容

该不该将单体架构迁移到微服务?生成性对抗网络——数据生成的高级解决方案SpringBoot对Spring MVC都做了哪些事?(四)软件架构中的跨层缓存技术人生 | 如何设定业务目标SpringBoot:如何优雅地进行响应数据封装、异常处理?为什么策略梯度法在协作性MARL中如此高效?终于有人把灰度发布架构设计讲明白了

编辑推荐

终于有人把Elasticsearch原理讲透了!花了一个星期,我终于把RPC框架整明白了!拜托!面试不要再问我Spring Cloud底层原理陌陌基于K8s和Docker容器管理平台的架构实践收藏 | 第一次有人把“分布式事务”讲的这么简单明了
我收藏的内容
点赞
收藏

AISummit人工智能大会