优化成果
先上结论,大家都没空! 经过两轮优化后 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` 。
所以油水还是有的,帮忙分享一波,说不定更新的更加快了呢!