MySQL压测时Linux中断异常飚高

作者阿里云代理 文章分类 分类:linux图文教程 阅读次数 已被围观 694

1. 系统环境

  • OS: CentOS Linux release 7.8.2003 (Core)
  • Kernel: 3.10.0-1127.19.1.el7.x86_64
  • MySQL: 用5.0、5.7均有此问题,应该和版本无关

2. 压测工具

  • benchyou[1]
  • mysql_random_load[2]

3. 问题现象

利用 mysql_random_load 工具连接MySQL写入数据时,性能非常非常低。

由于 mysql_random_load 工具不支持通过socket连接,只好放弃,改用benchyou。顺便说一下,benchyousysbench极为相似,也非常好用。

改用benchyou工具后,压测正常。看来的确不是MySQL版本的问题。

mysql_random_load 工具进行压测时,系统负载非常高,同时可观测到系统的中断也很高并且也很不均衡。

[root@yejr.run]# vmstat -S m 1 procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----  r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st  2  0      0  73585      2  41051    0    0   117    91    4    2  0  0 99  0  0  2  0      0  73585      2  41051    0    0     0 28320 55444 100207 18  2 80  0  0  4  0      0  73584      2  41052    0    0     0  1936 52949 98607 18  2 81  0  0  2  0      0  73583      2  41052    0    0     0  4864 56375 101262 14  2 84  0  0  4  0      0  73583      2  41052    0    0     0 29064 55806 103715 19  2 80  0  0  5  0      0  73583      2  41052    0    0     0  5704 55854 98386 15  2 83  0  0

可以看到 system.in 这列的值非常高,改成benchyou工具后,这列的值从5.5万降到1.6万。

[root@yejr.run]# vmstat -S m 1 procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----  r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st  4  0      0  77238      2  38371    0    0   118    88    2    3  0  0 99  0  0  2  0      0  77234      2  38374    0    0     0 31620 16039 77988  3  2 95  0  0  2  0      0  77231      2  38377    0    0     0 31996 16091 78926  3  2 95  0  0  3  0      0  77229      2  38378    0    0     0 33028 16347 81006  3  2 95  0  0  0  0      0  77226      2  38383    0    0     0 52412 15496 75715  3  2 95  0  0  2  0      0  77224      2  38384    0    0     0 32252 16167 79352  3  2 95  0  0

再看下有问题时的系统中断表现

[root@yejr.run]# mpstat -I SUM -P ALL 1 Linux 3.10.0-1127.19.1.el7.x86_64 (yejr.run)  09/28/2020  _x86_64_ (32 CPU)  05:37:40 PM  CPU    intr/s 05:37:41 PM  all  51833.00 05:37:41 PM    0   2069.00 05:37:41 PM    1   1159.00 05:37:41 PM    2   2979.00 05:37:41 PM    3   1580.00 05:37:41 PM    4   1627.00 05:37:41 PM    5   1461.00 05:37:41 PM    6   1243.00 05:37:41 PM    7   1825.00 05:37:41 PM    8   2154.00 05:37:41 PM    9   1367.00 05:37:41 PM   10   1277.00 05:37:41 PM   11   1376.00 05:37:41 PM   12   4085.00 05:37:41 PM   13   1601.00 05:37:41 PM   14   4045.00 05:37:41 PM   15   1857.00 05:37:41 PM   16   1692.00 05:37:41 PM   17    722.00 05:37:41 PM   18    118.00 05:37:41 PM   19   1862.00 05:37:41 PM   20   1637.00 05:37:41 PM   21   1130.00 05:37:41 PM   22   1750.00 05:37:41 PM   23   1653.00 05:37:41 PM   24   1417.00 05:37:41 PM   25   1547.00 05:37:41 PM   26   1500.00 05:37:41 PM   27   1033.00 05:37:41 PM   28     20.00 05:37:41 PM   29   1683.00 05:37:41 PM   30    888.00 05:37:41 PM   31   1549.00

可以看到每秒中断总量有5.5万,但多个CPU间并不均衡。

4. 问题分析

初步认定是因为系统中断太高导致的写入性能差,并且也认定是因为多个CPU间中断不均衡导致的这个问题。

观察是都有哪些中断比较高,发现主要是 LOC 和 RES 这两个每秒的增长比较大。

[root@yejr.run]# watch -d cat /proc/interrupts ... LOC: 2468939840 2374791518 2373834803 2373613050   Local timer interrupts SPU:          0          0          0          0   Spurious interrupts PMI:          0          0          0          0   Performance monitoring interrupts IWI:   50073298   45861632   45568755   45833911   IRQ work interrupts RTR:          0          0          0          0   APIC ICR read retries RES: 3472920231 3022439316 2990464825 3012790828   Rescheduling interrupts CAL:    5131479    6539715   17285454   11211131   Function call interrupts TLB:   23094853   24045725   24230472   24271286   TLB shootdowns TRM:          0          0          0          0   Thermal event interrupts ...

在尝试修改相关中断号绑定的CPU后(参考:SMP affinity and proper interrupt handling in Linux[3]),问题还是没有得到缓解。

后来某神秘大佬给指点了下,才发现原来是个内核的bug,涉及到参数 kernel.timer_migration,需要将其设置为 0 才行。

[root@yejr.run]# sysctl -w kernel.timer_migration=0

当然了,最好持久化写入到 /etc/sysctl.conf 文件中。

[root@yejr.run]# cat /etc/sysctl.conf  kernel.timer_migration=0  #加载配置文件使之生效 [root@yejr.run]# sysctl -p

再次用 mysql_random_load 工具进行压测就没事了。

下面是关于该bug的描述

The bug is when linux os receive too many tcp packages, and the tcp may add too many timer, but in get_target_base->get_nohz_timer_target it check current cpu is idle, sometimes thouth the current core is very busy, but the idle_cpu result is 1, in this time if set kernel.timer_migration=1 ,the timer will be move to next cpu.

bug详情见:Bug 124661 - kernel.timer_migration=1 cause too many Rescheduling interrupts[4]

最后,值得一提的是,在云主机上修改该参数应该是不管用,除非修改物理机的。我在某云主机上运行 mysql_random_load 工具压测也遇到类似问题,修改内核参数后问题依旧。

文内链接

  • [1]:https://github.com/xelabs/benchyou
  • [2]:https://github.com/Percona-Lab/mysql_random_data_load
  • [3]:http://www.alexonlinux.com/smp-affinity-and-proper-interrupt-handling-in-linux
  • [4]:https://bugzilla.kernel.org/show_bug.cgi?id=124661

全文完。

Enjoy Linux & MySQL :)

 

 

 

版权声明:本文内容转发自阿里云社区,由阿里云实名注册用户自发贡献版权归原作者所有本站不拥有其著作权,亦不承担相应法律责任。如果您发现本中有涉嫌抄袭的内容,请联系站内客服,本将立刻删除涉嫌侵权内容。

本公司销售:阿里云、腾讯云、百度云、天翼云、金山大米云、金山企业云盘!可签订合同,开具发票。

我有话说: