mongodb 4.2–5.x中config server高负载的直接原因是事务元数据强依赖config.transactions集合的全局写锁,导致跨分片事务并发受限;6.0起改用本地缓存+异步刷盘缓解,但prepare阶段集中写入、网络分区重试及wiredtiger缓存不足仍会引发config server压力。

Config服务器高负载的直接原因:事务元数据强依赖 config.transactions 全局锁(4.2–5.x 版本)
在 MongoDB 4.2 到 5.x 的分片集群中,所有跨分片事务的状态都必须写入 config.transactions 集合。这个集合位于 config server 上,且其更新操作默认持有全局写锁。只要有一个事务在提交、回滚或心跳续期,就会阻塞其他事务的元数据写入——哪怕它们操作的是完全不相关的分片。高并发短事务场景下,config.transactions 成为明显的单点瓶颈。
MongoDB 6.0 后的缓解机制:本地缓存 + 异步刷盘替代全局锁
6.0 并未取消 config.transactions,但改变了它被访问的方式:
- 事务协调器不再每次心跳都同步写 config server,而是先更新所在 shard 的本地内存缓存;
- 元数据变更以异步方式批量刷入
config.transactions,降低锁争用频率; - 读取事务状态时优先查本地缓存,仅在必要时(如故障恢复)才拉 config server 数据;
- 该优化需配合
transactionLifetimeLimitSeconds缩短(默认 30 秒),否则缓存过期策略会失效。
注意:db.adminCommand({ "setParameter": 1, "transactionLifetimeLimitSeconds": 15 }) 可进一步收紧,但低于 10 秒易触发 TransactionTooOld 错误。
为什么 config server 负载仍可能飙升?三个典型诱因
即使启用 6.0 优化,以下情况仍会让 config server 承压:
- 大量跨分片事务同时进入两阶段提交的
prepare阶段——此时协调器必须向所有参与 shard 发起同步请求,并最终汇总写入 config server; - 网络分区导致部分 shard 失联,协调器持续重试并记录失败状态到
config.transactions,引发高频小写入; -
wiredTigerCacheSizeGB设置过低,导致事务内存页频繁淘汰,WiredTiger 触发WT_ROLLBACK,进而反复重建事务上下文并刷新元数据。
验证方法:db.runCommand({ serverStatus: 1 }).metrics.commands.update 中关注 config.transactions 相关操作的 total 和 failed 计数;同时检查 db.serverStatus().wiredTiger.cache["pages evicted by application threads"] 是否持续增长。
真正要盯住的不是 config server,而是协调器所在 shard 的资源水位
事务协调器运行在某个具体 shard 上(由第一个写操作决定),它的 CPU、内存和磁盘 I/O 才是事务吞吐的隐性天花板。config server 高负载往往是协调器卡顿后的“症状”而非“病因”。比如:
- 协调器 shard 的
wiredTigerCacheSizeGB不足,导致自身事务处理变慢,拖长整个 2PC 流程,间接放大 config server 请求密度; - 该 shard 上同时运行大量非事务写入,与协调器争抢 WiredTiger 内存页和 eviction 线程;
- 事务内含
$lookup或重复更新同一文档,引发WriteConflict回滚重试,使协调器反复发起 prepare/commit 请求。
所以排查时别只盯着 config server 的 CPU,先用 db.currentOp({ "secs_running": { "$gt": 5 } }) 查看协调器所在 shard 上是否有长时间运行的事务操作。











