副本集各节点必须单独设置wiredtigercachesizegb,因每个mongod进程独立运行、各自维护缓存,若共用同一配置(如32gb机配16gb缓存用于16gb机),secondary启动即可能oom;arbiter无需设置;需按节点物理内存扣减os预留、线程开销等后计算,并通过db.serverstatus().wiredtiger.cache验证。

副本集每个节点必须单独设 wiredTigerCacheSizeGB,不能照搬同一数值——否则主从切换后 Secondary 很可能直接被 OOM Killer 杀掉。
为什么副本集里 wiredTigerCacheSizeGB 不能统一配
每个 mongod 进程独立运行、各自维护 WiredTiger 缓存,不共享也不感知其他节点内存规格。比如 Primary 部署在 32GB 机器上设了 wiredTigerCacheSizeGB: 16,Secondary 却跑在 16GB 机器上还用同样配置,启动时缓存就占满物理内存,触发系统级 OOM。
- Arbiter 节点完全不用设该参数——它不存数据、不走 WiredTiger 引擎
- Hidden/ReadOnly 节点如果承担读流量(
readPreference: secondary),也得按自身内存规格算,不能“跟着 Primary 走” - 滚动升级或节点替换时,配置文件同步容易漏,启动参数更可控
怎么算每个节点该设多少 GB
不是简单取物理内存的 50%~60%,而是要扣掉:OS 预留(至少 2GB)、oplog 应用线程开销、复制线程缓冲区、以及事务场景下快照内存预留(若开启多文档事务)。
- 32GB 物理内存节点:建议
--wiredTigerCacheSizeGB=12(而非 16) - 16GB 物理内存节点:建议
--wiredTigerCacheSizeGB=6(而非 8) - SSD 存储可上浮 5%~10%,机械盘建议压到 45%~50%
- 事务活跃场景(如金融类业务):再往下压 1~2GB,并同步调小
maxTransactionLifetimeMinutes
怎么验证设置是否生效
连上每个节点执行 db.serverStatus().wiredTiger.cache,只看这一行:"maximum bytes configured" : 12884901888(即 12GB × 1024³)
- 如果显示值明显大于你设的数值,说明配置没加载成功——检查是用了配置文件还是启动参数,优先以
mongod --wiredTigerCacheSizeGB=6方式启动 - 如果
"bytes currently in the cache"长期 > 95% ofmaximum bytes configured,说明工作集已撑满缓存,要么加内存,要么优化查询/索引 - 如果
"tracked dirty bytes in the cache"占比超 20%,需调大eviction=(threads_max=8,threads_min=4)
最容易被忽略的是:某个 Secondary 临时被切为 Primary,但它内存规格更低,而 wiredTigerCacheSizeGB 还按旧 Primary 的规格配着——这种错位不会立刻报错,但会在高负载或长事务时突然 OOM。











