
刘迪
腾讯云数据库产品总监
网名迪 B 哥,中国计算机行业协会开源数据库专业委员会副会长、北京航空航天大学特聘讲师。拥有视频、游戏、金融、电商等行业的多年数据库架构设计和优化分析经验,曾担任腾讯视频、腾讯新闻、腾讯体育等业务的数据库管理和运维负责人,对外推出了《迪 B 课堂》、《我说》等一系列数据库实战课程。加入腾讯云后,主导了腾讯云数据库 MySQL 的企业化转型,云原生数据库 TDSQL-C 的孵化以及 AI 与数据库自治等核心项目。
数据库技术经过数十年的发展,经历了从单体数据库到分布式数据库,再到如今开始向云原生技术靠拢的过程。作为国内自研数据库品牌的先行者之一,腾讯 TDSQL-C 在云原生数据库研发方面也早有布局。在 2022 年第六期 DBTalk 技术公开课中,腾讯云数据库产品总监刘迪带来了主题为《新一代云原生数据库 TDSQL-C 关键技术突破》的分享,介绍了 TDSQL-C 核心架构层面的一些重要技术成果。
领跑市场的云原生数据库

上图是典型的传统云数据库架构示意。传统云数据库一直以来还在沿用搬迁式的模式,这种架构中,云数据库提供的服务更多类似于云上托管,帮助用户实现、维护高可用组件和生态链路,但实际上数据库软件同传统的 MySQL 软件没有什么区别,只是从云下用户 IDC 部署变成了基于云厂商提供的底座。所以它依然没有突破传统数据库遇到的性能、回档效率、维护成本等方面的瓶颈。

腾讯云数据库的云原生架构就是要真正解决以上问题。我们在核心面上解决了铁三角效率问题:
首先,客户在使用资源时可以减轻业务层的开发负担。例如很多游戏行业客户有全球同服的需求,传统数据库主从延迟很大,网络链路非常长,于是业务层面要做多地、多活,做双份数据对照,业务层会很繁重。如果我们能够提供高效的复制链路,为用户做全球数据库多活、多地架构,就会减轻业务层的开发负担。数据库如果能够实现性能自调优,也能提升用户使用资源的效率。
第二,数据库资源被云厂商管理,云原生同架构可以提高运营效率。云原生架构使用算存分离的设计减少了算存资源的耦合,减少了资源配比的限制,用户就能获得更多资源红利。
最后,云原生架构在可靠性、可用性上都有非常大的提升。
云原生数据库关键技术解读
TDSQL-C 是新一代云原生数据库架构,整体采用算存分离的架构设计。我们的计算节点提供了 SQL 引擎、事务引擎以及两级加速缓存组件,存储采用了共享存储的方式做到多个计算节点共享同一份数据。
首先这个设计做到了百分百兼容 MySQL 协议,不管用户原先使用什么版本的 MySQL 软件,从传统架构到新一代云原生架构的迁移一定是平滑的,不需要用户更改任何业务代码,更改任何常用开源组件。
第二,该架构提供了单节点超百万 QPS 的性能,突破了传统数据库的性能瓶颈。它在存储侧的优势更加明显,基于扩展表空间可以实现单实例超过 PB 级的存储,不再需要分库分表就能实现海量存储需求。
该架构也提供了比传统数据库更高的可靠性和可用性保障。通过异步回滚、并行事务回滚等机制,单个计算节点出现故障以后能够快速拉起一个新的计算节点实现数据的高可用替换。
弹性扩展能力上,因为我们下面用的是共享存储,所以扩展能力完全同数据量没关系,不管数据量多大都可以基本实现秒级扩展。我们也通过极致的弹性和伸缩能力和 Serverless 架构大幅降低了用户的使用费用。
下面从三个方面讲一下我们的关键技术。

很多人对算存分离的认识是比较模糊的。而我们眼中的算存分离不是简单把 MySQL 的传统集中部署搬迁到虚拟化部署,把本地 IO 变成网络 IO,而是重构了 MySQL 原生数据流。我们选择的数据流格式具备很好的数据密度,这样才能够降低传输的数据量,抵消掉本地 IO 和网络 IO 的影响。第二,因为我们是在做算存分离,我们把所有的日志都推到了存储侧并行回放,希望在做部署解耦的同时,在架构上也能解耦。我们的存储侧基于这个数据流能够独立回放出数据页面,不依赖于一些元信息。
那么数据页面应该是解析难度最低的数据流,为什么没有选择它?因为它的数据密度过低,选择它以后通过网络传输的数据量依然会非常大。第二个问题是逻辑日志,大家都知道我们执行的 SQL 请求的数据密度是最高的,但需要依靠逻辑日志来回放的数据页要依赖很多元信息,还要依赖很多库表信息,所以存储层独立解析的难度非常大。基于这两点考虑,我们选择了物理日志作为数据变化的增量日志实现传输。选择这个数据结构以后,原先 MySQL 写一个 1K 数据可能要刷 16K 左右的页面,基于逻辑日志改写以后,不管是计算节点到存储节点,还是计算节点之间,用户写 1K 数据,可能只需要 1KB 加上几个字节就能够完成数据流的下推传输,数据在远端可以回放并持续持久化,从而提升性能,同时兼顾扩展性。
日志的持久化过程是什么样子的?我们采用了 log is database 的设计模式,只要利用增量的物理日志就能够实现逻辑日志的重构、数据页面的回放,保证数据在存储节点持久化。第一步是从计算节点到存储节点传输日志并持久化,日志持久化以后就认为这个事务完成了提交,可以返回客户端的请求。之后我们基于存储侧就可以并行、多进程进行数据页面的回放,通过回放出数据页面,包括底层的三个副本来保证数据的强一致。根据单个数据日志,我们会回放出多种数据页面的版本,实现多个计算节点访问存储节点的多版本需求。最后,直到所有计算节点日志都推进到最新的编号后,动态回收存储层多版本的数据页面,把日志回放开销等都下沉到存储层。
计算层节点第一做到了无状态,第二做到了计算层的资源能够完全为用户的请求服务,不需要有额外的开销去支持数据库层面数据的 merge、持久化等。我们可以在存储层基于分布式的共享存储架构,用多进程并发回放来提升数据页面的回放效率。基于物理日志的同步过程很好地解决了原先用逻辑日志在做数据同步导致的数据延迟过大问题。MySQL 传统基于 Binlog 的同步延迟大概到秒级别,但我们的云原生架构能够做到毫秒级别的延迟。
我们在软件设计上基于了定制的 TXSQL 内核,是腾讯团队自研的内核版本。它不仅针对官方的内核版本做了很多特性增强,给云上用户提供一些针对业务侧的价值提升,同时我们也主动提交给了一些官方开源社区做出贡献。比如我们的 InstantDDL 就是针对海量数据的库表结构变更,我们能够将变更写到元数据,通过元数据的变更实现秒级变更。我们经常会有一些误操作,传统应对方法一般来说是用全量数据加上增量的 Binlog 快速回档。到了云原生数据库以后,我们可以通过快照加上增量的 Redo log 提供回档。我们的闪回查询能力还支持查看每一个数据行上不同时间内多版本的数据。比如凌晨 4 点的时候删除了数据,5 点钟发现,这个时候就可以很快查到凌晨 4 点被删除前的数据,进行单个 SQL 的更新。在小范围点的数据行的快恢复比原先用存量数据加增量数据的恢复来说,效率是提高非常多的。
下面介绍我们的并行查询能力。现在复杂 SQL、OLAP 请求越来越多,传统 MySQL 对这种 AP 类请求支持的能力非常低,大量聚合操作在 MySQL 上面,随着数据量增加可能就跑不动了。一般来说企业都是通过 ETL 的方式再桥接外挂一个 AP 系统,或者直接 ETL 到大数据系统里面做异步分析,实时性、效率、成本都面临比较大的挑战。
我们基于云原生的架构,在内核上实现了并行查询的能力,打破了 MySQL 单个 SQL 只能利用一个核心的设置。我们能够让单个 SQL 有多个进程来执行,利用机器上多核 CPU 的能力来保证单个复杂的 SQL 在这种情况下能够有很好的执行效率。

原理上分为几个阶段,第一个叫做 SQL 的串行化优化阶段,基于串行的执行计划作为输入,这样就不用针对每个串行单独适配或开发,在支持语法的灵活性、覆盖数据结构的丰富面上都有非常好的提升。做完串行优化后,我们再做第二步语句检测,看这个语句到底适不适合做并行。有些语句可能没有命中并行的可执行结果,还有一种情况是它本身就是非常快的点查,其实并行并没有办法加速它的查询。第三步会做并行优化动态管理分区。原先的并行线程作为用户线程,既起到了汇聚的作用,同时还起到了协调者线程的作用,它要动态划分 SQL 请求下涉及的数据页面。我们去动态规划线程的分布,接着生成并行任务下发到并行线程,并行线程执行以后通过任务调度系统汇聚到数据的主线程以及用户线程。
我们可以简单地理解成,把原先一个大的数据集切分成若干个可并行执行的小数据段,在小数据段里聚合或者排序以后,再汇聚到主线程进行提交。比起资源有限的情况下靠一个大进程去执行这么大数据量的操作来说,会有比较大的性能提升。基于标准的 TPC-H 的测试结果,我们可以发现整体性能提升普遍在 10 倍到 20 倍之间。在后续的研发过程中我们也会做从一阶段提交到二阶段提交的演进,对语法、数据结构、数据类型的支持度会不断提升,覆盖更多场景。
云原生数据库能够做到大幅超过传统数据库的性能,在软硬结合方面也要下很大功夫。我们在这方面做的一项重点工作就是通过提升网络传输链路的效率提升数据库的性能。我们做的一项升级就是将计算节点之间的同步链路,以及计算节点到存储节点的同步链路、存储节点多个副本间的同步链路,都从传统的 TTP 网络升级到了 RDMA 网络。TTP 网络裸协议会出现反复上下文切换或者内存态拷贝,还有封装协议的一些影响,所以整体开销还是比较大的。通过 RDMA 网络采用的无内存拷贝,可以直接给访问用户态的数据降低这一部分协议开销。网络升级以后从原先的 240 微秒的效率提升到现在 20 到 30 微秒的效率,结合数据库的业务场景,性能提升大概在 70%到 80%。
第二个方面是编译器优化。我们同英特尔联合做了编译优化的工作提升通用性能。我们利用 oneAPI DPC++/C++编译器,结合链接时优化(LTO)和配置文件引导优化(PGO)的方法对应用程序进行模块间优化(IPO), 允许对代码实现深入分析和进一步的优化,来达到更好的性能。配置文件引导优化则向编译器提供程序中最常被执行区域的信息。这些优化使云原生数据库 TDSQL-C MySQL 性能得到显著提升,最高可达 85%。

我们做的第三件事是基于硬件的持久化内存。在计算节点上除了原先的内存,以及存储侧冷数据以外又加了一层微数据,提升用户的读写性能。比如 buffer pool 里的数据被淘汰后,我们可以直接写入到计算节点上的持久化内存的二级缓存里,通过二级缓存的加持使读写性能比原先要基于大量 remote IO 的场景有更好的提升。
最后一个技术点的加持就是 AI。我们在数据库的智能诊断上提供了大量的辅助工具提升云原生数据库的可用性、可靠性。我们基于上述内核特性的插件、审计日志来提供全链路审计日志的性能分析,进行自动的根因分析、性能检测,并针对复杂问题提供很好的优化模板,对简单问题能够进行自优化。我们采用了代价预估模型,在运用修改之前就能够通过 SQL 执行的 CPU 开销、IO 开销以及动态 memory 开销来评估优化以后的效果,预先效果告知用户,实现预判。
AI 的智能调参是比较大的工作,我们引入了深度强化学习算法,通过神经网络拟合的方式加快学习的精准度。我们能够做到边学习边训练,在成功中学习,也能够在失败中学习,激励源非常多样。我们还有一些后台提升并行度的能力,能够加速用户的回放来提升样本采集的精准性,快速调整出让用户更加满意的参数组合。
云原生数据库典型场景案例
TDSQL-C 云原生数据库已经应用在了腾讯内部的一些明星业务,比如大家常用的微信、QQ、腾讯视频、财付通的一些金融业务,以及腾讯会议、腾讯音乐上面,国民级的 APP 上大量底层都已经替换为了云原生的数据库服务。我们外部的客户,包括金融行业、政务、互联网等海内外的很多企业都已经把他们的数据库架设在了云原生数据库的底座上,使用云原生数据库也给他们的业务带来了很多收益。
零售客户经常遇到线上大促时底层数据库难以应付压力的情况,而通过向云原生数据库的迁移就可以得到巨大的提升。整个迁移过程中除了数据方面的搬迁以外,业务没有做任何改造。迁移上来后,他们下半年在双 11 和双 12 的大促活动里就没有再出现扩容升级滞后的情况,系统监测到了负载和资源损耗到比较高的瓶颈后,利用云原生架构的快速弹性横向扩容,可以实现秒级资源和承载 QPS 翻倍提升。

上面这两个社交领域客户也是从传统数据库直接升级到了云原生数据库,是非常典型的案例。他们有大量海外业务,社交类的业务又对延迟非常敏感,原本的开源分布式数据库方案成本高,效率增加并不明显。通过我们的替换,首先把他的成本打下来,打到了原先 1/3。第二个基于云原生数据库的海量存储,我们也给他们做了数据的归一聚合,之前 16 个实例合并到了一个大的实例上,不仅减少了他们多库多实例的运维压力,同时也提升了原先多个实例的性能。

上面也是我们重点在支持的两个客户,一个是团油,是为车主服务的 APP。他们经常会有大量秒杀场景需要提前准备,提前测算当时的活动可能会有多少峰值流量,预购计算资源。使用云原生数据库架构升级以后,我们通过秒级升配和秒级横纵扩展,使得他们在这方面的能力大幅提升。游戏行业上,我们支持了 B 站的百万 QPS 性能提升,承载了他们的一个人气手游的运营,给他们提供了全球同服的产品能力,而且维护成本也下降了,用户的游戏体验也更好了,跨国际同步延迟从原先的十几秒下降到了百毫秒级别。
未来已来:Serveless
最后一个章节简单分享一下我们在现在很火的 Serverless 架构上面的一些技术实现,还有一些客户储备。Serverless 这两年非常火,云原生数据库时代大家更关注的是性能、稳定性、可用性。但随着现在整个市场大环境的变化以及技术的成熟,用户在享受了这么多基础能力的红利以后,又希望我们能够提供又好用、又稳定、又高效而且又便宜的产品形态。我们在云原生架构上生长出来的 Serverless 提供了极致弹性的产品能力,为用户提供了大量极简化的数据运维体验和极致的成本压缩。用户不需要关心业务需要多大资源规格,我们可以根据用户业务负载进行动态扩缩。对于一些峰值非常明显、波动非常明显,有一些高度不确定性的业务,Serverless 能够为用户显著降低使用成本。
我们的 Serverless 数据库目前已经为大量的开发者、中小微企业提供了极致弹性和极致成本的数据库体验。我们微信小程序后台的数据库已经完全替换成了 Serverless DB,帮助用户省去了非常多的数据库维护成本、资源购买成本,数据库的使用复杂度也得到了明显降低。




