副本集节点cpu占用过高大概率是mongod进程内部问题,需用top确认是否mongod持续占用>80% cpu,再通过mongostat查看实时操作分布(如update突增、faults非零、locked%>10%),结合db.currentop()定位并kill超时操作。

副本集节点 CPU 占用过高,大概率不是硬件问题,而是某个操作正在持续吃掉单个线程资源 —— top 能帮你快速确认是不是 mongod 进程本身在飙 CPU,mongostat 则能告诉你「它在忙什么」。
用 top 确认是不是 mongod 进程真正在耗 CPU
别直接信监控图。先登服务器跑 top,然后按 P(大写)按 CPU 使用率倒序,看排第一的是否是 mongod 进程:
- 如果
%CPU列长期 >80%,且COMMAND是mongod,说明问题确实在 MongoDB 内部,不是其他进程抢资源 - 注意
TIME+字段:如果某个mongod进程的运行时间特别长(比如几小时),但 CPU 占用又高,很可能是某个长事务或后台任务卡住了 -
top -c | grep mongod可以过滤出完整命令行,确认是否启用了--config或带了非默认参数(比如--wiredTigerCacheSizeGB设得太小会逼它频繁刷盘,间接拉高 CPU)
用 mongostat 看实时操作分布,揪出异常模式
mongostat 不是查慢查询的工具,它是看「当前每秒都在干啥」的快照。在副本集主节点上执行(从节点也行,但主节点更能反映写入压力):
- 重点关注
query、getmore、insert、update、delete这几列的数值:如果某一项突然比平时高 5–10 倍(比如update从 200/s 跳到 2000/s),基本就是业务侧在批量刷数据,没走批量接口 -
faults列非零要警惕:表示 WiredTiger 缓存页缺失,频繁换页会把 CPU 拖进内核态做内存管理,这时候即使 QPS 不高,CPU 也可能虚高 -
locked %如果持续 >10%,说明锁争用严重,常见于大量短 update 操作更新同一字段(比如计数器),或者集合级操作(如createIndex)正在后台跑 - 加
-n 30多看几轮,避免误判瞬时抖动;加--host rs0/mongo1:27017,mongo2:27017可直连副本集,不用先连 primary
结合 currentOp 快速 kill 掉已知问题操作
mongostat 告诉你「哪类操作多」,db.currentOp() 告诉你「具体哪个操作在作妖」。进 mongo shell 后立刻执行:
-
db.currentOp({ "secs_running": { "$gt": 5 } }):只查运行超 5 秒的操作,避免被海量短操作淹没 - 重点看
ns(集合名)、op(操作类型)、query(实际条件)、secs_running和locks字段 - 如果看到
"op": "command"+"command": { "aggregate": ... }+"secs_running": 120,十有八九是没加$limit或没走索引的聚合;直接db.killOp(<opid>)</opid>干掉 - 别 kill 正在做
background:true索引构建的操作 —— 它本来就会跑很久,kill 会导致重建中断、索引损坏
真正容易被忽略的是:mongostat 的 netIn/netOut 如果远高于历史均值,说明客户端在发大量小包(比如每条日志都单独 insert),而不是批量提交 —— 这种问题不会出现在慢日志里,但会让 CPU 长期维持在 60%+,必须从应用层改逻辑。











