分片集群是MongoDB应对高并发写密集场景的唯一可扩展方案,但需科学设计分片键、优化mongos路由、保障配置服务器性能,并权衡writeConcern与journal以提升吞吐。

分片集群是 MongoDB 应对高并发写密集场景的唯一可扩展方案,但直接上分片不等于自动扛住百万 QPS —— 分片键设计、写路由路径、配置服务器压力这三处最容易被低估。
分片键选错会导致写热点,shardCollection 不能随便执行
写密集场景下,分片键决定所有写请求最终落在哪个分片。如果选 _id(默认 ObjectId)或时间戳字段(如 created_at),新写入会持续打到同一个分片(“尾部热点”),其他分片闲置。
- 优先用高基数 + 写分布均匀的字段组合,比如
{"user_id": 1, "event_type": 1},避免单字段单调递增 - Hash 分片(
{"user_id": "hashed"})能强制打散,但牺牲范围查询能力;范围分片({"region": 1, "timestamp": 1})支持时间窗口查询,但需监控 chunk 均衡度 - 执行
sh.shardCollection("db.coll", {"user_id": "hashed"})前,必须确认该集合无活跃写入,否则会触发 chunk 拆分风暴,拖慢整个集群
mongos 节点成为写瓶颈时,扩容不是加机器就完事
mongos 是无状态路由层,但每个写请求都要经过它解析、校验、转发。当单个 mongos CPU 持续 >70%,或连接数接近 ulimit,写延迟会陡升。
- 不要只靠增加
mongos实例数:客户端必须启用连接池(如 Node.js 的maxPoolSize),否则每次请求新建连接反而加重路由负担 - 关闭不必要的功能:禁用
mongos的enableSharding日志(setParameter logLevel=0),减少日志刷盘开销 - 写密集场景建议每个
mongos绑定专属 CPU 核心(taskset -c 0-3 mongos ...),避免与其他服务争抢调度
配置服务器(Config Server)在高写频次下容易元数据阻塞
每次 chunk 迁移、分片添加、或写触发自动拆分,都要更新 Config Server 上的路由表。若 Config Server 副本集(CSRS)磁盘 I/O 饱和,整个集群写操作会卡在 “waiting for config server update” 状态。
- Config Server 必须用 SSD,且
dbpath单独挂载,禁止与 Shard 共享磁盘 - 调大 WiredTiger 缓存:在
mongod --configsvr启动时显式设置--wiredTigerCacheSizeGB 4(默认 1GB 不够) - 避免高频手动干预:禁用
sh.splitAt()和sh.moveChunk(),让自动均衡器(balancer)按默认策略(每 2 小时检查一次)工作;手动迁移只用于紧急修复
真正压测时,最常被忽略的是写确认级别(writeConcern)和 journal 行为 —— w:1 + j:false 可把单分片写吞吐拉高 3–5 倍,但代价是节点宕机可能丢最近几秒数据;这个权衡点不在架构图里,而在每个 insertOne() 调用的参数里。


















