mongos CPU高通常源于客户端连接异常或后端shard响应慢;它仅做路由转发,不执行聚合排序等计算,CPU飙升多因连接堆积、重连频繁或shard全表扫描导致请求滞留。

mongos 节点的 CPU 高,大概率不是 mongos 本身在计算
mongos 是无状态路由层,不执行聚合、排序、$lookup 等耗 CPU 操作(除非开启 enableSharding 后的某些聚合下推),它真正干的活只有解析查询、路由转发、结果合并。所以看到 top 里 mongos 进程 CPU 占用高,首先要怀疑:是不是客户端在疯狂建连接、重连或发送大量小包?
- 用
pidof mongos拿到 PID,再跑top -p <pid></pid>看 %CPU 和 %MEM,确认是否真高(注意:16 核机器上 100% ≠ 满载,要看单核是否打满) - 检查
netstat -an | grep :27017 | wc -l和mongostat --host <mongos_host>:27017 1</mongos_host>的conn值是否接近——如果前者远大于后者(比如 2 倍以上),说明大量连接卡在 TIME_WAIT 或应用没复用连接池 - Java 应用常见坑:
connectionsPerHost设得过高(如 200+),又没配maxConnectionLifeTime,导致连接长期闲置但不释放
内存占用高 ≠ 内存泄漏,mongos 不缓存数据但会吃连接元信息
mongos 不维护 WiredTiger cache,也不缓存文档,但它要为每个活跃连接维护上下文(如 session、事务状态、分片路由表快照)。所以内存增长通常和连接数、并发查询复杂度正相关,而非数据量。
-
db.serverStatus().mem在 mongos 上基本无意义(字段为空或固定值),别信它——mongos 的内存必须看 OS 层:ps aux --sort=-%mem | grep mongos - 如果
RES持续上涨且不回落,重点查是否有未关闭的长连接(比如客户端用了startSession()但没endSession())或未清理的游标(db.currentOp({ "secs_running": { "$gt": 300 } })) - 配置项
maxConns默认不限制,但实际受系统ulimit -n限制;若频繁报connection refused,先查cat /proc/<pid>/limits | grep "Max open files"</pid>
别只盯着 mongos,真正的 CPU/内存压力在后端 shard
mongos 自身 CPU/内存异常,90% 是下游 shard 响应慢导致请求堆积、连接滞留、线程池打满。比如一个简单 find 查询因 shard 上缺失索引而全表扫描,mongos 就得一直等着,连接挂着,CPU 空转轮询。
- 立刻在 mongos 上执行
mongostat --host <mongos_host>:27017 1</mongos_host>,盯住qr(读队列)和qw(写队列):非零且持续增长 → 请求在 mongos 层堆积,根源在某个 shard 响应慢 - 对
qr/qw高的 mongos,连上去跑db.currentOp({ "secs_running": { "$gt": 5 } }),看host字段指向哪个 shard —— 那就是真瓶颈节点 - 然后跳到那个 shard 的 primary 上,用
mongotop 1看哪张表占total时间最多,再用db.collection.explain("executionStats").find(...)确认有没有COLLSCAN或docsExamined >> nReturned
监控部署建议:轻量采集 + 关键阈值告警
mongos 不适合跑 heavy exporter(比如 mongodb_exporter 开 full metrics),它本身是性能敏感组件。只需暴露最轻量级指标即可定位问题。
- 用 cron 每 30 秒跑一次:
mongostat --host <mongos_host>:27017 --noheaders 1 1 | awk '{print $2,$3,$4}'</mongos_host>(取 conn/qr/qw),写入本地文件或发到 Prometheus node_exporter textfile collector - 告警阈值设三档:
conn > 80% of ulimit -n、qr > 5 or qw > 5 连续 3 次、netstat 连接数 > 2 * mongostat.conn - 不要依赖
db.serverStatus()查 mongos 内存/CPU——它返回的是空壳,OS 层的ps和/proc/<pid>/statm</pid>才真实
真正卡住 mongos 的,从来不是它自己,而是它等的那个 shard 上一条没走索引的查询、一个没关的游标、或者一块被其他进程霸占的磁盘。盯指标时,眼睛要穿过 mongos,直接落在后端节点的 mongotop 和 iostat -x 1 输出上。


















