Zabbix Server突然报“High swap space usage ( less than 50% free)”,简单描述一下当前Zabbix Server环境,操作系统为CentOS 8,上面部署了MySQL与Zabbix-Server、PHP等组件。
[root@Zabbix ~]# more /etc/redhat-release
CentOS Linux release 8.2.2004 (Core)
[root@Zabbix ~]# uname -m
x86_64
登录Zabbix服务器检查内存情况如下所示:
[root@Zabbix ~]# free -m
total used free shared buff/cache available
Mem: 7809 4911 153 71 2744 2529
Swap: 8099 4082 4017
[root@Zabbix ~]# cat /proc/zoneinfo |grep -E "Node|pages free|nr_inactive_anon|nr_inactive_file|min|low|high"|grep -v "high:"
Node 0, zone DMA
nr_inactive_anon 318071
nr_inactive_file 531494
pages free 3836
min 32
low 40
high 48
Node 0, zone DMA32
pages free 21648
min 6091
low 7613
high 9135
Node 0, zone Normal
pages free 14002
min 10771
low 13463
high 16155
Node 0, zone Movable
pages free 0
min 0
low 0
high 0
Node 0, zone Device
pages free 0
min 0
low 0
high 0
Linux服务器空闲的内存还有不少,但是使用了大量的Swap空间(使用接近一半的Swap分区)。使用vmstat观察(si/so指标)也能看到有较频繁的内存页面置换到Swap分区或从Swap分区写入到内存)
si:每秒从交换区写到内存的大小;
so:每秒写入交换区的内存大小;
[root@Zabbix ~]vmstat -an 1
我一度怀疑是服务器没有禁用NUMA,导致MySQL耗用了大量的交换分区空间,因为MySQL的一个Bug#, 会导致MySQL在x86系统下存在严重的 “swap insanity” 问题,简单来说,你把主机大部分内存分配给InnoDB时,你会发现明明操作系统还有很多内存,但是却有很多内存被交换到了SWAP分区。网上也有大量这样的案例,但是,分析过程中,我分析、统计哪些进程占用了swap 大小时,惊奇的发现php-fpm进程耗用大量的swap空间。如下所示
for file in /proc/*/status ; do awk '/VmSwap|Name/{printf $2 " " $3}END{ print ""}' $file; done | sort -k 2 -n -r | less
重启php-fpm服务,发现系统swap分区使用率急剧下降,看来确实是php-fpm的进程耗用了大量的swap空间
#systemctl restart php-fpm
在/etc/php-fpm.d/www.conf配置文件中,找到php的错误日志文件:php_admin_value[error_log] = /var/log/php-fpm/www-error.log, 但是在错误日志中仅仅看到“error log file re-opened”,自己对PHP不太熟悉,没有继续深入探究。
[root@Zabbix ~]# cd /var/log/php-fpm
[root@Zabbix php-fpm]# ls
error.log error.log-20201025 error.log-20201101 error.log-20201108 error.log-20201115
[root@Zabbix php-fpm]#more error.log
[15-Nov-2020 03:28:01] NOTICE: error log file re-opened
[18-Nov-2020 17:06:21] NOTICE: Terminating ...
[18-Nov-2020 17:06:21] NOTICE: exiting, bye-bye!
[18-Nov-2020 17:06:22] NOTICE: fpm is running, pid 205515
[18-Nov-2020 17:06:22] NOTICE: ready to handle connections
[18-Nov-2020 17:06:22] NOTICE: systemd monitor interval set to 10000ms
结论:
在诊断问题过程,我一度被“MySQL在x86系统下存在严重的 “swap insanity” 问题”这个先入为主的观念给固定思维模式了,分析一直偏离了正确方向,直到我统计、查看哪些进程消耗了Swap空间时,才恍然大悟,然来是php-fpm进程异常了,然后又着急验证猜想,重启了php-fpm服务,导致一些问题没法验证,例如php-fmp的进程数量等等。另外,对于php不熟悉,不能进一步深入分析。不过倒是可以给一个简单结论是:php-fpm异常了,导致其消耗了大量Swap空间,至于是内存泄露还是其它原因已经无法探究了!