mongos内存持续上涨主因是连接池管理缺陷与版本Bug;需检查sh.status()异常、显式限制connPoolMaxSharded/NonShardedConnections、升级至修复版本并避免应用层频繁重建连接。

mongos 内存持续上涨但连接数稳定?先查 sh.status() 和 db.serverStatus().mem
mongos 本身不存储数据,内存泄漏往往不是业务查询导致的,而是内部元数据同步或配置刷新异常。最直接的线索藏在 sh.status() 输出里——如果看到大量重复的 shard 条目、config server 连接状态反复切换,或者 db.serverStatus().mem 中 resident 持续上涨而 mapped 基本不变,基本可以排除是缓存膨胀,指向连接管理或心跳逻辑的问题。
实操建议:
- 用
mongostat --host <your-mongos-host>:27017</your-mongos-host>观察netIn/netOut和conn是否脱钩(连接数不动但流量涨) - 定期抓取
db.currentOp({secs_running: {$gt: 5}}),重点看是否有卡在refreshing config cache或loading chunk metadata的操作 - 检查
/proc/<mongos-pid>/status</mongos-pid>的VmRSS,确认是否真在增长(避免被VmSize干扰)
连接池未显式配置?默认值在 4.2+ 版本中会加剧泄漏
mongos 默认使用 maxPoolSize=100,但它对 config server 和每个 shard 的连接池是**独立维护**的。如果你有 8 个 shard + 3 个 config server,理论最大连接数可达 1100,而这些连接一旦因网络抖动进入 connecting 状态又未及时超时,就会堆积为僵尸连接对象,持续占内存。
实操建议:
- 启动 mongos 时强制指定连接参数:
mongos --configdb rs0/cfg1:27019,cfg2:27019,cfg3:27019 --setParameter maxConns=2000 --setParameter connPoolMaxShardedConnections=30 --setParameter connPoolMaxNonShardedConnections=20 -
connPoolMaxShardedConnections控制每个 shard 的连接上限,connPoolMaxNonShardedConnections控制 config server 连接上限,二者必须显式设小(推荐 ≤30),否则 4.4+ 版本中后台刷新线程可能反复新建连接而不复用 - 避免在应用层再配
maxPoolSize,mongos 不识别驱动传来的这个参数,纯属冗余
升级到 4.4.22 / 5.0.16 / 6.0.8 之前,别碰 enableSharding 自动分片触发场景
这是个真实存在的版本 Bug:当 mongos 在执行 sh.enableSharding("db") 后,若紧接着快速执行 sh.shardCollection,且目标 collection 尚无 chunk,mongos 会在后台不断重试加载元数据,每次失败都新建一个连接池实例,但旧实例不释放。该问题在 JIRA 的 SERVER-62312 中确认,影响 4.4.0–4.4.21、5.0.0–5.0.15、6.0.0–6.0.7。
实操建议:
- 检查当前版本:
mongos --version,输出含gitVersion,比对 MongoDB 官方 Release Notes 中对应 patch 版本 - 临时规避:执行
sh.enableSharding("db")后,手动等待 3 秒,再执行sh.shardCollection;或先插入一条 dummy 数据让 collection 被自动创建,再分片 - 生产环境切勿使用
sh.stopBalancer()后长期不启,balancer 停止期间元数据刷新逻辑异常,也会诱发同类泄漏
应用端频繁重建 mongos 连接?mongos 实例不能当短生命周期对象用
有些 SDK 或框架(如某些 Python 的 pymongo 封装、Node.js 的 mongodb 早期版本)会把 mongos 地址当成普通 replica set 处理,在连接失败后直接 new 一个新 client 实例——这会导致每个新 client 都初始化一套独立的后台线程和连接池,旧的 mongos 进程无法回收资源。
实操建议:
- 确认应用中是否在每次请求都调用
MongoClient("mongodb://mongos-host:27017"),必须改为单例复用 - 检查连接字符串是否误加了
&replicaSet=参数,mongos 不支持 replica set 模式,加了会导致驱动降级为 direct connection 行为,绕过 mongos 的路由逻辑 - Java 用户注意:
com.mongodb.MongoClient(3.x)已废弃,务必升级到com.mongodb.client.MongoClient(4.x+),后者对 mongos 的连接管理更健壮
真正难排查的是那种混合了版本 Bug 和应用误用的情况:比如用 4.4.18 的 mongos,又在 Spring Boot 里配了 @Bean @Scope("prototype") 的 MongoTemplate。这时候光调参数没用,得两边一起改。

















