那些用Go实现的分布式事务框架(二)

简介: 那些用Go实现的分布式事务框架(二)

开篇


上一篇那些用Go实现的分布式事务框架我们主要介绍的是seata-golang。一个对标seata的go语言实现,当然版本还是落后Java版很多的。


这次我们来介绍一下另一个go实现的分布式事务:dtm。

首先来看下dtm整体架构图(来源官网)


1668514258805.jpg


再来看之前的seata架构图


1668514269753.jpg


从架构上来看,大差不差。


seata中的TC对标dam的TM。


RM两边意思一致。


seata中的TM对标dtm事务SDK。作用都是一样:第一阶段开启一个全局事务,执行各RM分支事务,第二阶段根据RM第一阶段执行结果,决定调用TC(seata)|TM(dtm) commit或者rollback。


架构上,个人感觉只是因为模块名称以及图画不一样的差别,当然在实现细节上还是有很大差别的


我们先简单介绍下DTM各个模块。


TM


TM 层在代码中是没有具体的主体结构的,开始都是函数之前的调用。


启动TM实际上开启了两个服务,http以及grpc这两个服务


1668514290038.jpg

http路由


1668514300295.jpg


gRPC接口


1668514310620.jpg


即然提供了两个服务入口,那理所当然有公共处理核心业务的部分


1668514347810.jpg


TM对数据的存储管理并不是依赖于接口,而是依赖于common.DB 结构。根据配置文件中DB.driver 的值决定底层数据库是mysql还是postgres两种


1668514359357.jpg


再看这个DB结构,所以本质上无论底层是哪种数据库,都是直接依赖gorm来对数据进行操作的


1668514369530.jpg


接着,看下TM是如何通知各个RM进行commit或者rollback的?

举一个TCC模式的例子。


TCC的两个阶段。

  • 阶段一: try。尝试执行,调用各RM自定义的try行为,预留必要的业务资源。
  • 阶段二:Confirm(阶段一所有参与本次事务的try行为都成功)。调用各分支事务的Confirm方法,真正执行业务,并且只使用try阶段预留的资源。
  • 阶段二:Cancel(阶段一任一参与本次事务的try行为失败)。调用各分支事务的Cancel方法,释放一阶段try所预留的资源。


从上面我们可以得知,TCC模式下,TM在第二阶段要么通知各分支事务Confirm要么Cancel。


在注册各RM事务分支到TM的时候,最终TM会为每一个分布式事务的参与者(RM)生成两条分支信息。


就像这样,


1668514387889.jpg


对,就是把对应的RM资源操作地址直接存入。


当TM接收到commit或者rollback命令,在处理完自身逻辑(一般就是修改Gloable状态),就需要开始处理每一个注册进来的分支事务了,说白了就是需要调用各个分支事务对应操作的接口。


1668514403672.jpg

这里的t.getProcessor() 是需要根据当前事务的类型(TCC、SAGA、XA)获取到对应的处理器来进行逻辑的处理


1668514414182.jpg


当然,每个事务处理器只需要实现接口


1668514429050.jpg


真正调用RM资源服务地址的时候,分为http和grpc,这是由开发者决定的


1668514440241.jpg


在v1.6之前的版本,grpc的请求是很简单粗暴解析地址方法然后连接的


1668514452080.jpg


现在为了支持那些采用gRPC Resolver 机制之上的一些微服务框架接入,做了一块抽象。感兴趣[1]可以看下,这里就不介绍了


SDK


至于SDK,每一个事务模式都是独立的,本质上是没有关联的。比如下面我们启动一个TCC分布式事务。这个分布式事务是由两个服务组成,简称+30和-30的服务


1668514464480.jpg


从上面的调用中我们还是能还原出整体流程。


  • 调用TM,得到一个分布式id
  • 调用TccGlobalTransaction函数开启分布式事务。
  • 调用TM prepare(这步只是为了查看第一步产生的那个分布式事务状态是否处于prepare。这里没看明白,此时还未注册执行分支,全局状态不是应该只会存在初始化状态吗)
  • 上一步没问题,执行传入的闭包函数,即CallBranch 函数里向TM注册参与事务的TM分支。注册完成后,开始第一阶段调用各分支的try服务。
  • 各分支try服务调用结束,根据第一阶段结果决定通知TM是submit还是abort。


另外提一点,分布式事务常见的一些问题:比如空补偿、重挂等问题。

一般情况下,业务需要自行去处理这种场景,以免造成不可描述的错误。

dtm里面提供了对应子事务屏障方案。核心就在


1668514480931.jpg


其实就是利用数据库的唯一索引机制,当然每个RM资源你都得新增一张表。


上面提到,dtm的TM角色本质上就是对应 seata 中的 TC,但是他们的处理模式是不同的。


dtm中的TM会根据注册时的各分支保存的地址,决定通过http还是rpc调用各RM操作,是由TM直接发起对RM的请求。


seata-go的实现中,TC是不参与直接调用RM的。

还记得上篇提到一个双向流RPC接口(BranchCommunicate)。TC通过这个接口把对应分支处理信息传递给RM管理器


1668514495484.jpg


然后由RM管理器根据事务类型选择对应的事务管理器进行处理,最终调用的是对应事务类型管理器的BranchCommit方法


1668514506342.jpg


下面是一个TCC事务类型管理器的处


1668514515637.jpg


对应的事务RM管理器是如何通知、处理各个RM资源的。

原理就是我上篇提到的作者实现的一个全局事务代理模式,本质上是利用go的反射实现的,感兴趣的可以自己去扒下源码,也可以看看作者对实现全局事务代理的介绍[2]


总结


这篇文章主要介绍了dtm实现的一些细节,从这两篇文章大体能看出实现上的部分区别,更多的细节还得靠自己去挖掘。


最后再问几个问题,

  • 日常开发中你们哪些场景是用到了分布式事务?用的是哪个框架还是自研的?
  • 或者说在分布式环境下,一致性的问题你们是如何解决的


相关


相关文章
|
26天前
|
Java 数据库
在Java中使用Seata框架实现分布式事务的详细步骤
通过以上步骤,利用 Seata 框架可以实现较为简单的分布式事务处理。在实际应用中,还需要根据具体业务需求进行更详细的配置和处理。同时,要注意处理各种异常情况,以确保分布式事务的正确执行。
|
26天前
|
消息中间件 Java Kafka
在Java中实现分布式事务的常用框架和方法
总之,选择合适的分布式事务框架和方法需要综合考虑业务需求、性能、复杂度等因素。不同的框架和方法都有其特点和适用场景,需要根据具体情况进行评估和选择。同时,随着技术的不断发展,分布式事务的解决方案也在不断更新和完善,以更好地满足业务的需求。你还可以进一步深入研究和了解这些框架和方法,以便在实际应用中更好地实现分布式事务管理。
|
2天前
|
分布式计算 大数据 数据处理
技术评测:MaxCompute MaxFrame——阿里云自研分布式计算框架的Python编程接口
随着大数据和人工智能技术的发展,数据处理的需求日益增长。阿里云推出的MaxCompute MaxFrame(简称“MaxFrame”)是一个专为Python开发者设计的分布式计算框架,它不仅支持Python编程接口,还能直接利用MaxCompute的云原生大数据计算资源和服务。本文将通过一系列最佳实践测评,探讨MaxFrame在分布式Pandas处理以及大语言模型数据处理场景中的表现,并分析其在实际工作中的应用潜力。
15 2
|
19天前
|
开发框架 Go 计算机视觉
纯Go语言开发人脸检测、瞳孔/眼睛定位与面部特征检测插件-助力GoFly快速开发框架
开发纯go插件的原因是因为目前 Go 生态系统中几乎所有现有的人脸检测解决方案都是纯粹绑定到一些 C/C++ 库,如 OpenCV 或 dlib,但通过 cgo 调用 C 程序会引入巨大的延迟,并在性能方面产生显著的权衡。此外,在许多情况下,在各种平台上安装 OpenCV 是很麻烦的。使用纯Go开发的插件不仅在开发时方便,在项目部署和项目维护也能省很多时间精力。
|
25天前
|
存储 Java 关系型数据库
在Spring Boot中整合Seata框架实现分布式事务
可以在 Spring Boot 中成功整合 Seata 框架,实现分布式事务的管理和处理。在实际应用中,还需要根据具体的业务需求和技术架构进行进一步的优化和调整。同时,要注意处理各种可能出现的问题,以保障分布式事务的顺利执行。
45 6
|
25天前
|
数据库
如何在Seata框架中配置分布式事务的隔离级别?
总的来说,配置分布式事务的隔离级别是实现分布式事务管理的重要环节之一,需要认真对待和仔细调整,以满足业务的需求和性能要求。你还可以进一步深入研究和实践 Seata 框架的配置和使用,以更好地应对各种分布式事务场景的挑战。
28 6
|
23天前
|
消息中间件 运维 数据库
Seata框架和其他分布式事务框架有什么区别
Seata框架和其他分布式事务框架有什么区别
23 1
|
28天前
|
Go API 数据库
Go 语言中常用的 ORM 框架,如 GORM、XORM 和 BeeORM,分析了它们的特点、优势及不足,并从功能特性、性能表现、易用性和社区活跃度等方面进行了比较,旨在帮助开发者根据项目需求选择合适的 ORM 框架。
本文介绍了 Go 语言中常用的 ORM 框架,如 GORM、XORM 和 BeeORM,分析了它们的特点、优势及不足,并从功能特性、性能表现、易用性和社区活跃度等方面进行了比较,旨在帮助开发者根据项目需求选择合适的 ORM 框架。
76 4
|
28天前
|
中间件 Go API
Go语言中几种流行的Web框架,如Beego、Gin和Echo,分析了它们的特点、性能及适用场景,并讨论了如何根据项目需求、性能要求、团队经验和社区支持等因素选择最合适的框架
本文概述了Go语言中几种流行的Web框架,如Beego、Gin和Echo,分析了它们的特点、性能及适用场景,并讨论了如何根据项目需求、性能要求、团队经验和社区支持等因素选择最合适的框架。
70 1
|
1月前
|
机器学习/深度学习 自然语言处理 并行计算
DeepSpeed分布式训练框架深度学习指南
【11月更文挑战第6天】随着深度学习模型规模的日益增大,训练这些模型所需的计算资源和时间成本也随之增加。传统的单机训练方式已难以应对大规模模型的训练需求。
132 3
下一篇
DataWorks