高性能数据访问中间件 OBProxy(八):揭秘高性能转发原理

2024年 5月 7日 43.8k 0

高性能是 OBProxy 的重要特性之一,为了实现 OBProxy 高性能特性,我们做了大量的工作。本篇文章我们将介绍 OBProxy 如何提升 OceanBase 数据库性能、OBproxy 单机性能优化工作以及 OBProxy 常见性能问题。

对于 OBProxy 性能,我们分为两个部分:

1、提升 OceanBase 数据库整体性能,如 OBProxy 的分区位置计算功能、LDC 路由功能、读写分离功能等

2、提升 OBProxy 单机性能,如更快的 SQL 处理速度、更高的 QPS 等

我们优先实现 OceanBase 数据库性能提升,然后再考虑 OBProxy 单机性能提升。

OBProxy 提升 OceanBase 数据库性能

对于提升 OceanBase 数据库的性能,经过长期的性能问题分析和排查,我们总结了四个方面的影响因素,了解这四点大家就掌握了 OBProxy 对 OceanBase 数据库的性能影响,下面我们进行详细介绍。

链路对性能的影响

引入 OBProxy 后,虽然整体链路上多了一个模块,但对性能影响不大,参考下面例子:

高性能数据访问中间件 OBProxy(八):揭秘高性能转发原理-1

我们比较连接 OBProxy 和连接 OBServer1 两种情况,假设数据分布在 OBServer2 上面,那么两种方式都需要两次网络交互。所以大部分情况下连接 OBProxy 和连接 OBServer 的性能差距不大,并且因为 OBProxy 转发效率更高,有时性能更好。

访问 OceanBase 数据库时,链路长度和模块的部署方式有很大关系。我们在第二篇文章介绍了 OBProxy 部署方式,提到 OBProxy 部署到应用端时性能最好。为了大家更方便的享受这种部署的好处,我们也研发了富客户端功能。所谓富客户端功能,就是指我们把 OBProxy 的功能打包成一个 so 动态库,JDBC/C驱动等加载该 so 就可以使用富客户端能力,而无需部署运维 OBProxy,我们以 Java 程序为例:

高性能数据访问中间件 OBProxy(八):揭秘高性能转发原理-2

使用富客户端只需要修改下配置的 URL 即可,不需要修业务的代码,非常方便上手。

除了富客户端,随着云原生技术的普及,中间件产品的 Mesh 化也是部署的一个重要发展方向。OBProxy 的 Mesh 产品 DBMesh 在蚂蚁内部也大量部署使用。因为 Mesh 化对底层架构如 k8s、pilot 配置中心等有要求,因此有一定的使用门槛。

总结一下,大家根据真实的机房环境,按照我们第二篇文章给出的几种部署方式选择合适的就行,如果对性能有极致要求可以尝试使用 OBProxy 的富客户端形态。

扩展性

当排查发现分布式系统中某个模块达到单机性能瓶颈时,此时再去想提升单机性能是一件非常困难的事情,而通过增加机器进行扩容可以快速解决性能瓶颈问题,因此扩展性就是一个影响性能的重要因素。

OBProxy 本身是无状态的,并且启动速度特别快,可以实现秒级提供服务,因此 OBProxy 的扩展性特别好。根据真实测试数据,OBProxy 可以在 1~2 s内完成启动提供服务。

另一方面,在双十一等高并发场景,OBServer 本身也经常做云上的弹入和弹出操作,本质就是 OBServer 的机器变更(上下线、扩缩容等)。OBProxy 感知 OBServer 的副本位置变更操作,在路由时选择正确的 OBServer 为用户提供服务,帮助用户有丝滑的使用体验。

数据路由

在第五篇文章我们介绍了路由影响因素,其中性能因素至关重要。为了更好的性能,我们实现了丰富的路由算法如 LDC 路由、Primary Zone 路由、读写分离路由等,大家可以回顾前面的数据路由文章。

在 OBServer 的新版本,我们也将要上线事务路由功能,事务内的 SQL 都可以发往数据所在的节点,性能也会变得更好。我们假设事务有两条 SQL:

之前版本事务路由:

高性能数据访问中间件 OBProxy(八):揭秘高性能转发原理-3

新版本事务路由:

高性能数据访问中间件 OBProxy(八):揭秘高性能转发原理-4

通过比较我们也可以发现新的事务路由更加的简单高效,减少 TCP 通信次数,并且可以更高效发挥每一台 OBServer 能力,性能提升有 50% 左右。

OBProxy 单机性能提升

本节我们介绍下 OBProxy 单机性能提升的一些工作,方法论的东西比较多,和大家做一下交流,主要分为三个方面:

1、在 OBProxy 的功能设计和编码实现时考虑性能影响,面向高性能编程,降低新功能带来的性能损耗

2、关注新的硬件、linux 内核和编译器技术,使用新技术带来性能优化

3、建立性能回归体系,对每个版本做严格性能回归,保证性能优化的成果

下面我们将展开介绍。

OBProxy 高性能设计

OBProxy 在设计之初就考虑了高性能:

  • 采用 C++ 语言编写,可以充分使用硬件、内核的特性,也减少一些语言的 GC 等机制对性能影响
  • 设计优秀的多线程模型,可以充分发挥每一个 CPU 核心的能力,架构上做到尽量简单
  • 编码时采用异步调用、内存池、减少 Buffer 拷贝等手段优化性能

如果用一句话概括,OBProxy 通过多线程和异步框架提供优异的性能。为了满足异步接口的使用,我们也做了一些牺牲,一个完整的流程会被切割成多段代码,对代码可读性有一定影响。

对于 OBProxy 的线程模型,下图描述了公有云上 OBProxy 在 16c 机器上的任务分发模型。线程主要分为两类:accept 线程和 work 线程。accept 有两个,work 线程有 16 个(根据 CPU 核数确定)。work 线程完全一样,accept 线程完成 TCP 建连后,会将对应的套接字轮询的发给每个 work 线程。每个 work 线程运行 epoll 机制, 进行套接字的读写、异常等处理工作。

高性能数据访问中间件 OBProxy(八):揭秘高性能转发原理-5

因此 OBProxy 可以做到 CPU 核心之间的负载均衡,充分发挥每一个核心的能力,不存在因为阻塞导致 CPU 利用率上不去的情况。

OBProxy 优化方向

虽然 OBProxy 有了优秀的线程模型和异步框架,但随着功能的不断丰富,对性能也会产生一定的损耗。此时为了提升性能,我们该怎么做呢?我们的做法是分为应用、编译器和内核、硬件三层去做性能优化。

应用层优化

对于应用层优化,我们不做具体工作介绍了,讲一下我们的方法步骤,常见做法分为四步:

1、确定优化场景:如数据库我们常选择 sysbench 中的场景或者 TPCC 场景

2、分析性能消耗:我们通过 perf 火焰图、打日志等一些手段获取性能消耗分布, 从大到小,模块、函数、代码语句层层拆分下去,明确问题点

3、提出解决方案:无论是从设计上还是 C++ 一些优化技巧(如减少拷贝、减少锁使用等)提出优化方案

4、验证优化效果:根据方案进行编码,并重新验证优化效果

对于大部分情况,我们发现应用层优化效果就会很显著。举个极端例子,某个客户性能不符合预期,我们调整了客户 Java 程序的日志级别,就发现性能有几倍的提升,都还未涉及到数据库层面优化。在 Github 的 OBProxy 项目下,文件 hotfuncs.txt 记录了影响 OBProxy 性能的重点函数。但对于 OBProxy 和 OBServer 这样经过长时间优化的项目,应用层优化的油水会越来越少。

译器和内核新特性使用

内核和编译器技术也在不断发展,在性能方面也会提供越来越多的新特性,我们关注这些技术发展并应用到我们实践中。

我们以编译器为例子,PGO 和 LTO 是编译器的重要发展方向,编译器可以帮助应用程序更好的利用 CPU 的特性,如帮助 CPU 更好的做指令预取等。OBProxy 也在升级适配新版本的编译器,将这些技术引入到项目中,提升 OBProxy 性能。

软硬件结合

对于硬件影响,我们举个例子,同一份 OBProxy 代码,只升级 Intel CPU 型号,性能就会有巨大差异。因此我们也需要关注硬件技术。硬件方面,我们探索 RDMA 在 OceanBase 数据库的使用。

对于 RDMA,除了大家知道的对延迟的影响,另一个重要作用就是 Bypass Kernel,节约 CPU,优化性能。

在分析 OBProxy 性能时,我们发现内核态进行 TCP 报文收发就可能占用 30% ~ 50% 的 CPU 资源。使用 Bypass Kernel 设计(参考下图),可以进一步提升 OBProxy 性能。目前在蚂蚁内部我们也在验证 RDMA 技术。

高性能数据访问中间件 OBProxy(八):揭秘高性能转发原理-6

OBProxy 优化成果保护

对于 OBproxy 项目,版本功能迭代是性能的一大杀手。新的功能特性意味着新代码引入,代码规模进一步变大。除了指令数增加,对 Cache 命中率等硬件特性影响也会导致下降。因此我们需要平衡好新功能开发对性能影响:

1、在性能设计时考虑性能影响,做评估好性能影响

2、建立完善的性能回归体系,发现每一次的性能变化,并做好记录

根据我们的工程实践,每个迭代性能损耗可以控制很好,在我们的预期范围内。

常见问题总结

问题分析方法论

下面我们分享总结我们一些性能优化方法论。

性能优化目的:

性能调优的目的旨在充分发挥软件和硬件的能力,在真实环境中实现系统的最佳性能,提高软硬件的性价比,降低客户的成本。

性能优化步骤:

1、确定优化目标:两个重要指标是吞吐量/延迟,如金融业务中延迟变大导致交易失败更加需要关注

2、压力测试及信息采集:因为性能压测往往伴随高并发等场景,所以需要尽量简化场景,更有利于问题分析

3、分析压力确定性能瓶颈:遵循从大到小原则,从整个系统拆分到某个模块,有模块进一步拆分,逐步攻克

4、实施优化:根据问题分析结果确定优化手段

5、确认优化效果:通过验证确定优化手段是否有效,如果无效需要重新分析

通用优化手段:

1、优化部署:我们做了很多介绍,大家参考我们的部署内容介绍

2、调整配置参数:了解常用参数参数对性能的影响,OBProxy 将大部分优化参数调整成默认值

3、分析及优化客户应用:性能优化方法论非常通用,也可以和客户交流,推动应用侧优化

4、负载均衡:OBProxy 有一些路由配置项,可以通过调整路由配置观察不同路由算法对性能影响

延迟问题排查

延迟问题分析的一个重要思路就是确定时间都去哪了。我们以一次云上延迟问题分析为例。

首先我们需要了解业务模型,以 sysbench 的 write_only 场景为例,客户端会发送如下 SQL:

BEGIN
UPDATE sbtest14 SET k=k+1 WHERE id=299
UPDATE sbtest25 SET c='44447767919-12274780880-99082970721-80233057876-56657929970-31232803895-99831366925-10847903674-03281233116-67159541952' WHERE id=253
DELETE FROM sbtest10 WHERE id=250
INSERT INTO sbtest10 (id, k, c, pad) VALUES (250, 252, '40759328906-38274427176-96674981047-99836330693-36612343492-26708648085-72288836314-84636340651-06191567091-70833666298', '76795660930-60533928600-47111820801-73921545159-04547938600')
COMMIT

第二步确定整体网络拓扑和 ping 延迟:

高性能数据访问中间件 OBProxy(八):揭秘高性能转发原理-7

第三步我们根据 OBProxy 的审计日志、慢日志、统计日志分析 OBProxy 行为(参考第三篇文章)。根据 OBServer 的 sql_audit 分析 OBServer 行为。

最后根据分析出来的结论,整体梳理整个性能问题,进行总结归纳。

并发问题排查

并发问题表现就是 QPS 上不去,对于 OBProxy,主要关注三点:

1、打印日志是否频繁:观察 OBProxy 打印日志的速度,如果 2~3s 就生成一个日志文件,那么性能肯定不好,正常应该几个小时或者一天生成一个,此时需要观察打印日志内容分析 OBProxy 行为;另一方面打印日志会导致 SQL 变慢,SQL 变慢又会触发打印慢日志,导致恶性循环

2、是否有远程计划:如果 OBServer 的 sql_audit 有大量远程计划,那么性能一般不会太好,此时需要分析问题原因,不同的原因有不同的处理办法

3、使用 perf top:可以通过 perf top 看 OBProxy 的函数 CPU 使用,如果有函数的 CPU 使用超过 5% (显示红色),就可以找专家协助看一下

上面三点基本就可以解决大部分的 OBProxy 问题。

OBProxy 性能指标

对于 OBProxy,大家也可以记录一些常用性能数据。OBProxy 单核性能在 2~4w 之间,云上 16c 测试约有 40w QPS。

OBProxy 没有明显性能热点函数,使用 perf top 观察每个函数 CPU 消耗都在 5% 以下。

OBProxy 工作线程建议配置和 CPU 核数一样,更多的线程数不会再带来性能提升。

对于 OBProxy 使用的协议,性能数据如下:MySQL 协议 > 2.0 协议 > 压缩协议。将压缩协议改为 MySQL 协议后性能会带来明显提升。

课后互动

上期互动答案

问:客户端发给 OBproxy 加密数据,那么 OBProxy 发给 OBServer 的一定是加密数据吗?

答:不一定,参考文章 SSL 介绍部分。OBProxy 收到客户端的加密数据后,会进行解密。然后根据配置决定是否需要重新加密数据发给 OBServer。

本期互动

问:OBProxy 如何利用 CPU 多核性能?

欢迎持续关注 OceanBase 技术社区,我们将不断输出技术干货内容,与千万技术人共同成长!!!

搜索🔍钉钉群(33254054),或扫描下方二维码,还可进入 OceanBase 技术答疑群,有任何技术问题在里面都能找到答案哦~

高性能数据访问中间件 OBProxy(八):揭秘高性能转发原理-8

相关文章

Oracle如何使用授予和撤销权限的语法和示例
Awesome Project: 探索 MatrixOrigin 云原生分布式数据库
下载丨66页PDF,云和恩墨技术通讯(2024年7月刊)
社区版oceanbase安装
Oracle 导出CSV工具-sqluldr2
ETL数据集成丨快速将MySQL数据迁移至Doris数据库

发布评论