随着我们国家的经济崛起,对国产化和自主可控的要求变得越来越高。

除了要求对于核心业务做到自主可控,还要求下探到基础软硬件,如操作系统、数据库、编译器、CPU等,做到全流程的信息技术把控。

在我负责的数据库和金融支付领域,更是国产化的前沿区域。

相信不出五年时间,我们会看到越来越多的银行、证券、保险等传统金融公司将核心业务跑在国产开源的芯片、操作系统、数据库上。

虽然,目前还存在不少挑战,但相信只要万众一心,中国人民的智慧一定能克服各种挑战。

今天,姜老师将分享在国产 Huawei TaiShan 2280 V2 CPU 上,优化 MySQL 8.0 版本,从而将性能提升近 40% ,达到百万的 QPS 。

ARM 版本 MySQL

ARM 版本 MySQL

Huawei TaiShan 2280 是基于 ARM 架构的 CPU 。

从命令 lscpu 输出的结果可以看到 Huawei TaiShan 2280 是小端(Little Endian)模式,即数据的高字节位保存在内存的高地址中。

打开网易新闻 查看精彩图片

低端模式与目前的 X86-64 CPU 一致,这意味着从理论上来说,可以直接将 X86-64 上的 MySQL 物理文件拷贝到 ARM 服务器,数据库是可以工作的。

测试的 Huawei TaiShan 2280 一共4个CPU,每个CPU 32核,总共128个逻辑核。

上图中的 Thread(s) per core 显示为1,表示与 X86-64 CPU 不同,没有超线程技术。

MySQL 8.0 要工作在 ARM CPU 架构下,官方没有二进制版本提供,需要通过源码编译。

最新的 MySQL 8.0 版本编译没有任何错误,一次编译即可全部通过。

打开网易新闻 查看精彩图片

接下去,通过之前自己编写的 my_test 程序,对 MySQL 8.0 在 Huawei TaiShan 2280 进行极限性能的压测。

MySQL 8.0 ARM 性能测试

MySQL 8.0 ARM 性能测试

之前的文章中,已经通过 my_test 进行了多次压测,同学应该有了一个基本的 MySQL 性能认知:

  1. 96 核逻辑 CPU 下,性能可以达到 140W QPS,~2.3W / Core;
  2. 通过 Memcached Plugin,性能可以达到 220W QPS,~ 5.3W / Core;

然而,当在 Huawei TaiShan 2280 CPU 上进行压测时,会发现虽然 CPU 的核数增加到了 128 核,但压测性能仅不到 75W QPS :

打开网易新闻 查看精彩图片

对于之前 MySQL 8.0 版本调优的一些配置都已启用,难道这就是 ARM 架构 CPU 的性能上限么?

这么快放弃是不可能的,结果也是不能接受的,所以姜老师决定继续排查问题。

先通过命令top查看下 CPU 的负载情况,然后计算单核能力:

打开网易新闻 查看精彩图片

从上图可以发现 MySQL 进程占用了约57个逻辑核,但 QPS 仅不到75W。

这样的话,单核能力约为:1.3 W / Core,仅为 X86-64 CPU的 56% 。

此外,可以发现系统负载也并不是特别高,仅占用 11.7%,也算比较正常。

初诊没有什么特别的线索。接着,进入到内核的角度看看数据库的开销,使用命令perf top -g -p `pidof mysqld`,得到如下结果:

打开网易新闻 查看精彩图片

这次有了一些线索,发现竟然函数btr_search_guess_on_hash开销占用达到近30%!

但展开函数 btr_search_guess_on_hash 的调用,其实并没有什么特别的问题,因为压测走主键查询,使用AHI是很正常的调用

打开网易新闻 查看精彩图片

对比 X86-64 CPU 测试过程中的 MySQL 内核开销:

打开网易新闻 查看精彩图片

可以看到虽然 X86-64 CPU 测试下函数 btr_search_guess_on_hash 的调用依然占用是最高的,但占用率不到 3%。

ARM CPU 下这个函数的开销提升了 10 倍!

然而如果去深究函数 btr_search_guess_on_hash ,其实并没有什么特别值得优化的点,因为他是加的是一把 S 共享锁:

打开网易新闻 查看精彩图片

在 my_test 主键测试下,这把锁不会有冲突,而且 AHI 已经默认拆成了 8 个 AHI 共享锁,加锁性能也已不再是瓶颈。

虽然有了一些线索,但还是不能有特别好的优化方案。

难道这就是 ARM CPU 该有的性能表现?

我不信!!!

进一步思考,为什么函数 btr_search_guess_on_hash 会占用大部分 CPU ?

因为每个用户测试线程最终都需要调用这个函数,但这个函数占用的 CPU 时间超过了 30%,在 128 线程测试下,超过50%。

这时,我将目光转移到 NUMA 的架构问题上,这在 X86-64 CPU 上也一样存在问题。

但 Huawei TaiShan 2280 拥有 4 个 CPU,NUMA 跨节点访问性能问题会更为突出。

通过命令 sar 可以发现 CPU 负载极其不平衡:

打开网易新闻 查看精彩图片

可以看到在CPU 0 和 1上的负载很低,超过60%是空闲的。而在 CPU 2 和 3 上,CPU负载较高。

在有了这个线索之后,可以通过命令 numactl 将 MySQL 进程绑定到指定的 CPU 上。

通过修改 MySQL 服务启动脚本,按如下操作即可进行绑定:

打开网易新闻 查看精彩图片

接着再运行测试程序 my_test,可以发现 QPS 跑到了 103 万,ARM CPU 单核能力达到了 1.9W / Core,性能相对之前有近40%的提升:

打开网易新闻 查看精彩图片

NUMA 性能优化并不仅仅是 MySQL 数据库的问题,所有程序在 NUMA 架构下都存在类似问题。

即便是 X86-64 CPU 也有同样的问题,只是我们测试务器 CPU 数量(物理 CPU 数量)没有这么多,表现还不是特别突出。

但不论 ARM CPU 还是 X86-64 CPU,通过将 MySQL 进程绑定到指定 CPU 的方式,都能提升单核 CPU 的工作效率:

打开网易新闻 查看精彩图片

总结

总结

今天姜老师带给同学们一种性能调优的技术,通过 numactl 将 MySQL 进程绑定到指定 CPU ,较少跨 CPU 节点访问带来的性能下降。

在 CPU 比较多的架构上,这个现象非常突出。

同时,这个问题并不是 ARM CPU 所独有的问题,X86-64 架构的 CPU 同样有类似的问题。

因此,在当前的超多核的 CPU 架构下,在 NUMA 架构无法透明编程和调优的前提下,都倾向于通过一些资源隔离的优化手段,将程序跑在指定 CPU 上,这样才能充分发挥多核的优势。

而这不就是云时代下的数据库使用姿势么?

BTW,姜老师的抖音账号粉丝数破1万啦~~~,欢迎关注抖音号:破产码农