共计 1296 个字符,预计需要花费 4 分钟才能阅读完成。
作者:任坤
现居珠海,先后负责专职 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/bin
wget https://raw.githubusercontent.com/brendangregg/perf‐tools/master/execsnoop
chmod 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。