第二轮:从 Linux 内核事件看 MySQL 性能瓶颈

2022-09-22 11:25:13 浏览数 (1)


优化成果

先上结论,大家都没空! 经过两轮优化后 MySQL 单个连接 tps 如下

优化前

第一轮

第二轮

158 tps

1673 tps

1924 tps

经过第两轮优化把性能提升到了原来的 12.18 (1924 / 158 ~= 12.18) ,下面来看一下这二次优化的过程。


书接上回

上回我们通过 linux 内核的 ebpf 模块观测能力定位了 MySQL 的瓶颈,并通过调整相应的 MySQL参数把 tps 由 158 提升到了 1673 ;但是从性能上讲我们还有提升的空间。

我们还是按照方法论走,先从整体上把握 linux 的资源使用情况。

代码语言:javascript复制
mpstat 1 30
Linux 5.14.0-55.el9.x86_64 (git-sqlpy-com)   07/21/2022   _x86_64_  (2 CPU)

01:30:15 AM  CPU    %usr   %nice    %sys %iowait    %irq   %soft  %steal  %guest  %gnice   %idle
01:30:16 AM  all   37.63    0.00    7.73   11.86    0.00    3.09    0.00    0.00    0.00   39.69
01:30:17 AM  all   38.38    0.00    7.07   14.65    0.00    3.03    0.00    0.00    0.00   36.87
01:30:18 AM  all   38.34    0.00    7.77   12.44    0.00    3.11    0.00    0.00    0.00   38.34
01:30:19 AM  all   36.04    0.00    6.09   13.20    0.00    3.05    0.00    0.00    0.00   41.62

可以看到 IO-WAIT 只有 10 % 了,说明这个不高;但是 CPU 的USR 使用率接近 40%,这个相对 IO 来讲就有点高,整体上不是特别协调。


分析问题

从上次优化后的资源使用情况来看(IO-WAIT 比较低),我们可以得出如下结论,如果有必要我们有能力用 IO 资源来置换 CPU 资源 (一个 10% 另一个 40% )。当然最终有没有必要我们还是要用数据说话,好在上次优化后的火焰图还在,它就可以提供数据。

`binlog_cache_data::compress` 这个压缩 BIN-LOG 的函数占用了 10.28% 的 CPU 资源;考虑到 BIN-LOG 是顺序 IO,且现在 IO 不是瓶颈,为了节约 CPU 那我要把压缩这个功能给“优化”掉。到此我们打算用 IO 资源置换 CPU 资源,打造了一个更加均衡的系统。


调整参数验证性能

由于我们的目标是性能,所以压缩 BIN-LOG 在这个目标下对我们是没有意义的。那么现在就调整 MySQL 参数,我们不再压缩 BIN-LOG ,不要让 CPU 做这种没有意义的事。

代码语言:javascript复制
mysql> set @@global.binlog_transaction_compression = OFF;
Query OK, 0 rows affected (0.00 sec)

再测试一下性能

代码语言:javascript复制
mtls-auto-fill --host=127.0.0.1 --port=3306 --user=root --password=xxx --database=tempdb --table=t --rows=50000 execute
Report:
------------------------------------
|tps = 1924.565426390742
|cost_time = 25.979891
------------------------------------
Compelete.

打火焰图看优化后的效果

代码语言:javascript复制
# 这里直接用的 ebpf 生态的工具
profile  -p 537985 -af 11 --stack-storage-size=163840 > /tmp/simple-insert-double-zero-binlog-not-compression.out

`trans_commit` 原本是一个双峰结构,右边的峰是在压缩 BIN-LOG 大概占用 10.28% 经过我们的参数调整已经把这块的消耗“拿掉”了。

并且最终的结果上看,最左边之前有一个叫 `syscall` 的峰也没有了(目前还分析不出这个调用是在做什么,别慌以后会填坑的),它在没有优化之前大概占用 5%

有了这两份数据我们从火焰图上也能大致推算出,这种 CPU 优化后的收益。一个 10% 另一个 5% ,也就是说,总的性能大致是之前的 115%,我们现在就可以估算一下提升。

代码语言:javascript复制
In [1]: 1673 * 1.15
Out[1]: 1923.949

我们的实测值是 `1924.565` 可以说是非常接近了。


还有没有油水

油水这个事比较好看,如果整体上没有那么就是没有了。

代码语言:javascript复制
mpstat 1 30
Linux 5.14.0-55.el9.x86_64 (git-sqlpy-com)   07/29/2022   _x86_64_  (2 CPU)

00:42:06 AM  CPU    %usr   %nice    %sys %iowait    %irq   %soft  %steal  %guest  %gnice   %idle
00:42:07 AM  all   32.16    0.00    9.55   17.59    0.00    3.02    0.00    0.00    0.00   37.69
00:42:08 AM  all   34.54    0.00   10.31   18.04    0.00    3.09    0.00    0.00    0.00   34.02
00:42:09 AM  all   36.18    0.00    8.54   18.59    0.00    3.52    0.00    0.00    0.00   33.17
00:42:10 AM  all   34.85    0.00    9.60   19.70    0.00    2.53    0.00    0.00    0.00   33.33
00:42:11 AM  all   33.85    0.00    9.74   21.54    0.00    4.10    0.00    0.00    0.00   30.77

可以看到在我们参数调整之后 usr 由之前的 40% 左右下降到了 34% 左右,IO-WAIT 由 10% 左右上涨了 20% 。也就是说整套系统由 40:10 的结构调整到了 34:20 的结构。算是均衡一点了。

再看一下 IO-WAIT 上升了 100%的原因 (由 10%上升到 20% 上升了 100%)。

代码语言:javascript复制
funccount -i 1 -p 111659 'vfs_*'
FUNC                                    COUNT
b'vfs_fsync_range'                        496
b'vfs_write'                             6159
b'vfs_read'                              8373

可以看到 sync 和 write 的比例关系发生了变化,由之前的 `292:7009` 变成了现在的 `496:6159` 。

所以油水还是有的,帮忙分享一波,说不定更新的更加快了呢!


0 人点赞