作者:刘晓敏

2022 年 4 月,中国电子云开源了其云原生数据库 Mesh 项目 DBPack。该项目的诞生,旨在解决用户上云过程中面临的一些技术难点,诸如分布式事务、分库分表等。由于它数据库 Mesh 的定位,意味着它可以支持任意微服务编程语言。

分布式事务

DBPack 的分布式事务致力于实现对用户的业务无入侵,它对 HTTP 流量和 MYSQL 流量做了拦截代理,支持 AT 模式(自动补偿 SQL)和 TCC 模式(自动补偿 HTTP 请求)。

DBPack 从 Kubernetes control loop 思想中获得灵感,采用 ETCD Watch 机制来驱动分布式事务提交回滚。在采用代理使连接增加一跳的情况下,它的性能相比采用 MYSQL 存储的分布式事务解决方案 seata-golang 性能提高了百分之 50。

AT 模式

AT 模式的性能取决于全局锁的释放速度,哪个事务竞争到了全局锁就能对业务数据做修改,在单位时间内,全局锁的释放速度越快,竞争到锁的事务越多,性能越高。从 ETCD 官方 Bench 测试数据中可以看到,ETCD 在高并发下,读写延迟很低,不同并发压力下写延迟 2 毫秒到 20 毫秒不等,读延迟基本在 10 毫秒以内。采用 ETCD 来存储全局锁是 DBPack 分布式事务性能提升的关键。

上图展示了 seata-golang 协调一个分布式事务的交互逻辑。从图上我们可以看出,事务发起者(TM)和事务协调者(TC)间存在创建(开始)全局事务提交(回滚)全局事务 RPC 交互。事务参与者(RM)和事务协调者(TC)间存在注册分支事务报告分支事务执行状态 RPC 交互。事务协调者(TC)和 MYSQL 交互保存状态数据。

而 DBPack 创建全局事务、注册分支事务只是在 ETCD 插入两条 KV 数据,事务提交回滚时修改对应数据的状态,DBPack Sidecar 通过 ETCD Watch 机制感知到数据的变化就能立即处理数据的提交回滚,从而在交互上减少了很多 RPC 请求。

各 Sidecar Watch 应用产生的数据,各自处理,实际上已经没有中心化的事务协调者,架构也变得简单了。核心的事务协调逻辑代码包括配置代码都比 Seata-golang 大幅减少。所以 DBPack 以全新的云原生的思路,带了更简洁的架构和更高的性能。

seata-golang 事务协调核心代码

dbpack 事务协调核心代码

DBPack 支持所有微服务编程语言,samples 中已提供了 Go 语言和 Java 语言的例子,PHP 和 Python 的例子也在开发中。

TCC 模式

提到 TCC 模式,大家可能第一时间想到 TCC 模式可能存在的问题:幂等性、防悬挂等。事务悬挂产生的原因是什么?其实这是一个很的问题!

APP1 在调用 APP2 的 Prepare 方法之前,事务框架根据上下文信息,自动把 Commit、Cancel 需要执行的方法名以及 Prepare 方法执行的上下文告诉事务协调者(注册分支事务),再执行 Prepare 方法。如果执行 APP1 调用 APP2 的 Prepare 方法的时候,发生网络问题,导致 APP2 迟迟没有收到 Prepare 请求,事务协调者经过一定时间后,认为全局事务超时,则 TC 根据注册上来的事务分支信息发起全局回滚,此时,APP1 向 APP2 发起一个 Cancel 请求,很巧的是,APP2 端 Cancel 请求比 Prepare 请求先到达,事务空回滚后,再收到 Prepare 请求,Prepare 如果正常执行了,那就完了,全局事务已经回滚了,这个 Prepare 操作永远也不会提交、回滚,事务挂起了,数据不一致了。

首先,这种概率很小,其次,为什么一定要在 Prepare 网络请求之前注册分支事务,可不可以在 APP2 收到 Prepare 请求执行业务代码之前注册,这时候一定能确定 Prepare 请求已经到了,Cancel 请求确定能在 Prepare 请求之后发生,是不是就不存在悬挂问题了。

实际上 seata-golang 诞生之时就支持在分支业务执行端注册 TCC 事务分支,但大家可能没有深入思考这个问题,机械地认为事务悬挂必然会发生。

DBPack 也是在请求到达 sidecar 后再注册 TCC 事务分支,确保 Prepare 先于 Cancel 执行。有人说因为 CPU 调度的原因,还是可能出现 Cancel 先于 Prepare 执行的情况,但这种概率非常非常低。具体到操作的业务数据,建议使用 XID 和 BranchID 加锁。

读写分离

DBPack 当前支持对 SQL 请求自动路由,写请求路由到写库,读请求路由到读库。在开启事务的情况下,请求自动路由到写库。同时,也可以通过 SQL Hint 自动路由读请求到用户指定的数据库。

分库分表

分库分表的功能目前还在开发中,当前已经支持跨分片、跨 DB 的查询请求,支持 Order By 和 Limit。

结语

更多特性我们也在积极开发中,DBPack 社区非常 Open,进入到社区我们都是平等的开源爱好者,在这里你也可以成长为大佬,欢迎感兴趣的同学与我们一起建设 DBPack 社区。进群或参与社区建设请添加微信:scottlewis。

链接

DBPack 项目地址:https://github.com/cectc/dbpack

DBPack 文档:https://cectc.github.io/dbpack-doc/#/

中国电子云数据库 Mesh 项目 DBPack 的实践的更多相关文章

  1. TypeScript在node项目中的实践

    TypeScript在node项目中的实践 TypeScript可以理解为是JavaScript的一个超集,也就是说涵盖了所有JavaScript的功能,并在之上有着自己独特的语法.最近的一个新项目开 ...

  2. Golang项目的测试实践

    Golang项目的测试实践 最近有一个项目,链路涉及了4个服务.最核心的是一个配时服务.要如何对这个项目进行测试,保证输出质量,是最近思考和实践的重点.这篇就说下最近这个实践的过程总结. 测试金字塔 ...

  3. Atitit 拦截数据库异常的处理最佳实践

    Atitit 拦截数据库异常的处理最佳实践 需要特殊处理的ex 在Dao层异常转换并抛出1 Server层转换为业务异常1 需要特殊处理的ex 在Dao层异常转换并抛出 } catch (SQLExc ...

  4. MySQL面试必考知识点:揭秘亿级高并发数据库调优与最佳实践法则

    做业务,要懂基本的SQL语句: 做性能优化,要懂索引,懂引擎: 做分库分表,要懂主从,懂读写分离... 数据库的使用,是开发人员的基本功,对它掌握越清晰越深入,你能做的事情就越多. 今天我们用10分钟 ...

  5. 前端项目模块化的实践3:使用 TypeScript 的收益

    以下是关于前端项目模块化的实践,包含以下内容: 搭建 NPM 私有仓库管理源码及依赖: 使用 Webpack 打包基础设施代码: 使用 TypeScript 编写可靠类库 使用 TypeScript ...

  6. 前端项目模块化的实践2:使用 Webpack 打包基础设施代码

    以下是关于前端项目模块化的实践,包含以下内容: 搭建 NPM 私有仓库管理源码及依赖: 使用 Webpack 打包基础设施代码: 使用 TypeScript 编写可靠类库 使用 TypeScript ...

  7. 前端项目模块化的实践1:搭建 NPM 私有仓库管理源码及依赖

    以下是关于前端项目模块化的实践,包含以下内容: 搭建 NPM 私有仓库管理源码及依赖: 使用 Webpack 打包基础设施代码: 使用 TypeScript 编写可靠类库 使用 TypeScript ...

  8. Web项目--------原Oracle数据库的项目同时兼容MySql

    原Oracle数据库的项目同时兼容MySql步骤: (一)修改资源配置文件applicationContext-dataSource.xml的数据库连接 Oracle数据库中加上from dual的原 ...

  9. Immutable.js 以及在 react+redux 项目中的实践

    来自一位美团大牛的分享,相信可以帮助到你. 原文链接:https://juejin.im/post/5948985ea0bb9f006bed7472?utm_source=tuicool&ut ...

随机推荐

  1. 处理器映射器(HandlerMapping)及处理器适配器(HandlerAdapter)详解(二)

    注解的 处理器映射器 和 处理器适配器 介绍 注解的映射器: 在 Spring3.1 之前使用 DefaultAnnotationHandlerMapping 注解映射器(根据 DispatcherS ...

  2. 学习ELK日志平台(一)

    一.需求及基础: 场景: 1.开发人员不能登录线上服务器查看详细日志 2.各个系统都有日志,日志数据分散难以查找 3.日志数据量大,查询速度慢,或者数据不够实时 4.一个调用会涉及到多个系统,难以在这 ...

  3. 学习 Haproxy (一)

    haproxy是一个开源的.高性能的基于tcp和http应用代理的HA的.LB服务软件,它支持双机热备.HA.LB.虚拟主机.图形界面查看状态信息等功能,其配置简单.维护方便,而且后端RS的healt ...

  4. Qt的.pro文件格式解析

    Qt的.pro文件格式解析 在Qt中用qmake生成makefile文件,它是由.pro文件生成而来的,.pro文件的具体格式语法如下: 1.注释 .pro文件中注释采用#号,从"#&quo ...

  5. 小程序web-view加载H5信息不全

    满足小程序的web-view标签跳转网页形式 配置小程序后台的web-view(业务域名) 可打开关联的公众号的文章 通常实现逻辑 页面加载的时候赋值于一个data对象的值,然后赋值到web-view ...

  6. java连接oracle数据库(转)

    在做导游通项目所用到 package org.javawo.test; import java.sql.Connection; import java.sql.DriverManager; /** * ...

  7. 有关表单autocomplete = "off" 失效问题解决方案

    一.autocomplete介绍 autocomplete是Html5中的新属性.该属性规定输入字段是否应该启用自动完成功能.自动完成允许浏览器预测对字段的输入.当用户在字段开始键入的时候,浏览器基于 ...

  8. java中什么叫多重捕获MultiCatch,它的用法是怎样的?

    2.多重捕获MultiCatch 马克-to-win:什么叫多重捕获MultiCatch?一段代码可能引起多个异常,这时可以定义两个或更多的catch子句来处理这种情况,每个子句捕获一种类型的异常.马 ...

  9. 适配手机端rpx像素

    <script src="static/js/adaptive.js"></script> <script type="text/javas ...

  10. Python入门-面向对象-特殊方法

    调用拦截功能 class Message: def send(self,info): print("消息发送:",info) class Me: def __getattribut ...