作者:任坤

现居珠海,先后负责专职 Oracle 和 MySQL DBA,当初次要负责 MySQL、mongoDB 和 Redis 保护工作。

本文起源:原创投稿

*爱可生开源社区出品,原创内容未经受权不得随便应用,转载请分割小编并注明起源。


1、背景

某我的项目的开发环境,单台虚拟机装了1套mongo集群用于测试,1个mongos + 3节点config + 1shard * 3正本,总计7个mongo实例。 mongo版本4.2.19,OS为centos 7.9。

测试完结后cpu负载始终维持在50%左右,而此时mongo的qps曾经降落为0。

这台机器上只装置了mongo,将所有mongo实例敞开,cpu负载立刻恢复正常,再将mongo实例开启,过了一会cpu负载又开始飙升。场景能复现,且确认是跟mongo实例有关系。

2、诊断

执行top命令,cpu的usr曾经达到了40%,然而前几个过程的%cpu加起来远远凑不够数。

查看mongos的qps,的确没有执行用户命令了。

dstat查看整体负载(vmstat格式化做的不好,最初几列总是对不齐整)。

除了cpu负载不失常,其余指标均失常,中断和上下文切换也不算高,不太可能是这两个引发的。
perf record -ag -- sleep 10 && perf report 查看cpu执行状况。

的确有大量mongo调用,然而API命名不直观,无奈猜想对应的执行逻辑。

至此,确认是mongo实例引发的问题,然而mongo的利用连贯为0,看调用API栈也找不到有用信息。

回到本文结尾,top过程的cpu利用率加起来远远小于cpu总体负载,大概率是有频繁短时过程偷走了这部分CPU资源,导致top命令来不及捕捉统计。

sar -w 1 查看每秒生成的过程数,均匀每秒新建80多个过程,应该就是它了。

要抓出频繁建设短时过程的利用,能够采纳execsnoop,该工具通过 ftrace 实时监控过程的 exec() 行为,并输入短时过程的根本信息, 包含过程 PID/PPID、命令行参数。

#下载execsnoop#cd /usr/binwget https://raw.githubusercontent.com/brendangregg/perf‐tools/master/execsnoopchmod 755 execsnoop 

以下是输入内容,全是监控零碎在执行,不停的连贯mongo并对输入后果执行grep过滤,每个操作都会衍生一个新线程/过程,10s捕捉 了400多条记录。

将zabixx过程敞开,cpu马上恢复正常,找到了首恶。

咱们其余环境也采纳了zabbix监控,然而都没有遇到相似问题。

该节点部署了7个mongo实例,zabbix默认对每个mongo实例都进行监控,相当于执行损耗放大了7倍,而该机器是一台只有4核CPU的虚拟机。

这些因素凑齐了就会暴发问题。 这是个开发环境,临时敞开了zabbix监控,后续要对监控逻辑进行优化,尽量减少连贯db的次数以及grep调用链的长度。

3、小结

当机器cpu负载继续低落却抓取不到top过程时,能够采纳execsnoop抓取短时过程,相似工具还有iosnoop、opensnoop。