rsyslog进程占用内存巨高
发生险情后,立即进行排查,发现有1个节点还没有完全僵死,还能连上,只是非常卡,现象是
- 1、内存被完全耗尽,系统swap被占用超过80%,操作非常卡顿
- 2、负载贼高,16核的机器负载达到120+
- 3、除了业务的进程占用内存高之外,还有一个进程占用内存也很高,rsyslogd
- 4、osd进程死的死,不死的也无法与外界通信
经过排查,业务进程占用超高内存是因为发生写入阻塞,发生写入阻塞的原因是什么呢?排查监控日志判断是内存不足,导致osd缓慢,写入延迟开始增大,发生业务阻塞,然后内存耗尽,于是开启了链式反应
内存不足的原因没有查到,之前加了监控的进程没有明显的内存问题,所以针对内存占用高的rsyslogd进程进行重启后,内存降下来了,集群恢复正常,然鹅,过了一段时间,rsyslogd进程的内存又不安份地快速增长了,这次决定深入排查
【1】fopen() failed: 'No space left on device', path: '/var/lib/rsyslog/imjournal.state.tmp'
(1)排查过程
查看进程状态,发现有相关报错信息
[root@server07 tanweijie]# systemctl status rsyslog.service ● rsyslog.service - System Logging Service Loaded: loaded (/usr/lib/systemd/system/rsyslog.service; enabled; vendor preset: enabled) Active: active (running) since 二 2019-08-13 10:53:53 CST; 1 weeks 1 days ago Docs: man:rsyslogd(8) http://www.rsyslog.com/doc/ Main PID: 5011 (rsyslogd) CGroup: /system.slice/rsyslog.service └─5011 /usr/sbin/rsyslogd -n 8月 21 08:50:42 server07 rsyslogd[5011]: fopen() failed: 'No space left on device', path: '/var/lib/rsyslog/imjournal.state.tmp' [v8.24.0 try http://www.rsyslog.com/e/2013 ] 8月 21 08:50:42 server07 rsyslogd[5011]: fopen() failed: 'No space left on device', path: '/var/lib/rsyslog/imjournal.state.tmp' [v8.24.0 try http://www.rsyslog.com/e/2013 ] 8月 21 08:50:42 server07 rsyslogd[5011]: fopen() failed: 'No space left on device', path: '/var/lib/rsyslog/imjournal.state.tmp' [v8.24.0 try http://www.rsyslog.com/e/2013 ] 8月 21 08:50:52 server07 rsyslogd[5011]: fopen() failed: 'No space left on device', path: '/var/lib/rsyslog/imjournal.state.tmp' [v8.24.0 try http://www.rsyslog.com/e/2013 ] 8月 21 08:50:55 server07 rsyslogd[5011]: action 'action 1' resumed (module 'builtin:omfile') [v8.24.0 try http://www.rsyslog.com/e/2359 ] 8月 21 08:50:55 server07 rsyslogd[5011]: action 'action 1' resumed (module 'builtin:omfile') [v8.24.0 try http://www.rsyslog.com/e/2359 ] 8月 21 08:55:01 server07 rsyslogd[5011]: action 'action 0' resumed (module 'builtin:omfile') [v8.24.0 try http://www.rsyslog.com/e/2359 ] 8月 21 08:55:01 server07 rsyslogd[5011]: action 'action 0' resumed (module 'builtin:omfile') [v8.24.0 try http://www.rsyslog.com/e/2359 ] 8月 21 23:53:02 server07 rsyslogd[5011]: action 'action 2' resumed (module 'builtin:omfile') [v8.24.0 try http://www.rsyslog.com/e/2359 ] 8月 21 23:53:02 server07 rsyslogd[5011]: action 'action 2' resumed (module 'builtin:omfile') [v8.24.0 try http://www.rsyslog.com/e/2359 ]
调查内存
[root@server07 tanweijie]# /usr/bin/cat /proc/5011/status|/usr/bin/grep -w 'VmRSS' VmRSS: 6916064 kB [root@server07 tanweijie]# free -m total used free shared buff/cache available Mem: 63844 44074 5399 3275 14370 14112 Swap: 0 0 0
对于内存已经比较吃紧的系统来说,接近7G的占用还是不能接受的,此前故障发现rsyslogd占用超过15G…
既然报了空间不足的错,看了下系统目录,没有发现空间不足~看了下监控日志,也没有发现这段时间有磁盘空间占满的情况
[root@server07 tanweijie]# df -h 文件系统 容量 已用 可用 已用% 挂载点 /dev/mapper/centos-root 50G 18G 33G 36% / devtmpfs 32G 0 32G 0% /dev tmpfs 32G 0 32G 0% /dev/shm tmpfs 32G 3.2G 28G 11% /run tmpfs 32G 0 32G 0% /sys/fs/cgroup /dev/sda1 1014M 142M 873M 14% /boot /dev/mapper/centos-home 1.1T 260G 775G 26% /home
解决办法
一轮google后,基本没有找到有用的信息,解决办法倒是找到不少,其中最简单的莫过于限制内存的使用(如果有读者朋友知道原因,欢迎指教)
下面我们通过限制这个rsyslog.service的最大使用内存,来保护我们的节点,这里又不得不再吹一次systemd的强大,记得在早前我们将进程绑定到指定的cpu运行的调研中.
发现可以在service文件中加入参数CPUAffinity
来指定程序运行的cpu,这里我们再次使用相同的套路,systemd支持的service配置再一次强大,相关参数:
可以看到,我们不仅可以限制RSS使用,还可以限制CPU、stack段大小、data段大小等,十分强大
另外,根据redhat的官方文档,还可以使用诸如CPUQuota=20%
、MemoryLimit=500M
等方式来实现进程的资源控制,不过这里我们未对这部分参数进行测试
加入这些限制的操作很简单
方法1:
首先打开进程的service,一定要加--full
,否则打开后是空白文件
# 任选其一 systemctl edit rsyslog.service --full vim /usr/lib/systemd/system/rsyslog.service
然后,加入参数,这里我们限制rsyslogd进程使用最大物理内存为1G,因此加入LimitRSS=1073741824
到service域中,cat一下看看
[root@server07 tanweijie]# systemctl cat rsyslog.service # /etc/systemd/system/rsyslog.service [Unit] Description=System Logging Service ;Requires=syslog.socket Wants=network.target network-online.target After=network.target network-online.target Documentation=man:rsyslogd(8) Documentation=http://www.rsyslog.com/doc/ [Service] LimitRSS=1073741824 Type=notify EnvironmentFile=-/etc/sysconfig/rsyslog ExecStart=/usr/sbin/rsyslogd -n $SYSLOGD_OPTIONS Restart=on-failure UMask=0066 StandardOutput=null Restart=on-failure [Install] WantedBy=multi-user.target ;Alias=syslog.service
方法2:
在 Service 配置中 添加MemoryAccounting=yes,MemoryMax=80M,MemoryHigh=8M
不管用哪个方法,重新载入并重启进程
[root@server07 tanweijie]# systemctl daemon-reload [root@server07 tanweijie]# systemctl restart rsyslog.service
最后,我们再次确认RSS限制是否生效
[root@server07 tanweijie]# ps -ef|grep rsyslog root 1289301 1 0 10:34 ? 00:00:00 /usr/sbin/rsyslogd -n root 1292065 1289493 0 11:03 pts/0 00:00:00 grep --color=auto rsyslog [root@server07 tanweijie]# cat /proc/1289301/limits Limit Soft Limit Hard Limit Units Max cpu time unlimited unlimited seconds Max file size unlimited unlimited bytes Max data size unlimited unlimited bytes Max stack size 8388608 unlimited bytes Max core file size 0 unlimited bytes Max resident set 1073741824 1073741824 bytes Max processes 255284 255284 processes Max open files 1024 4096 files Max locked memory 65536 65536 bytes Max address space unlimited unlimited bytes Max file locks unlimited unlimited locks Max pending signals 255284 255284 signals Max msgqueue size 819200 819200 bytes Max nice priority 0 0 Max realtime priority 0 0 Max realtime timeout unlimited unlimited us
可以看到,Max resident set
已经设置为1G,默认是unlimited的。
运行一段时间后,rsyslogd进程未见内存异常占用
总结
rsyslog进程此前我没有关注过,没有发现这个进程会占用大量内存的情况,其他环境也没有发现,所以很是奇怪。通过这次事件的解决,我们又掌握了精细化控制进程资源使用的手段,在service文件中设置指定参数,简单有效
参考资料
- 本文链接: http://www.strugglesquirrel.com/2019/09/06/集群运维大宝剑之内存耗尽排查/
- 版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 3.0 CN 许可协议。转载请注明出处!