应查看分片节点的data_iops监控值并与实例规格页标注的最大iops上限对比,若data_iops持续接近上限(如11000/12000),且iops_usage长期高于85%,即表明iops接近瓶颈;注意data_iops反映真实业务吞吐,log_iops高仅说明日志写入频繁。

怎么看分片节点的IOPS使用率是否接近瓶颈
阿里云MongoDB控制台里,IOPS使用率监控项只对部分架构生效:4.2以上云盘版副本集/分片集群才支持显示真实值;旧版单节点、4.2以下分片集群会恒为0,不能信。真要看,得结合两个地方:data_iops(数据盘实际I/O量)和实例规格页标注的“最大IOPS上限”。比如某Shard节点规格标称最大12000 IOPS,监控图里data_iops持续在11000+波动,就说明快顶满了。
- 注意区分
data_iops和log_iops:写日志频繁也会拉高log_iops,但真正影响业务吞吐的是data_iops - 如果
iops_usage长期高于85%,即使没报错,也要警惕——WiredTiger刷脏压力变大,查询延迟可能开始抖动 - 单个Shard节点的IOPS不是平均分配的:用
db.product.getShardDistribution()查完后,再挨个连到对应Shard的Primary上,跑db.currentOp({secs_running: {$gt: 1}}),看是不是有大量慢写在集中打某个分片
连接数饱和度怎么算才不算误判
连接数不是看mongos上总数,而是每个Shard节点自身的连接负载。mongos本身不存数据,它的连接数高只说明路由压力大;真正卡住写入的是Shard上的currentConnections。进Shell后执行db.serverStatus().connections,重点关注current字段——它代表当前活跃连接数,不是总连接池大小。
- 阿里云默认连接上限跟内存规格强相关:比如16GB内存的Shard,硬限制通常是2000左右;超过这个数新连接会被拒绝,错误信息是
Too many connections - 别只盯峰值:连续10分钟
current稳定在上限的90%以上,且伴随queued> 0(排队等待的连接),就是扩容信号 - 排查是否连接泄漏:对比应用端配置的连接池大小和
db.serverStatus().network.numRequests增速。如果请求量涨3倍但连接数只涨10%,大概率是应用没正确复用连接
为什么只看监控图容易漏掉真实瓶颈
监控粒度本身就有盲区。现在阿里云存量实例采集粒度可能是1秒、60秒或300秒不等,而I/O毛刺可能只有200ms——这种瞬时打满会直接被平滑掉。更关键的是,IOPS使用率和connection current都是聚合指标,掩盖了热点集合问题。
- 一个分片上95%的I/O来自
orders集合的update操作,其余集合几乎不动:这时扩容整个Shard是浪费,应该先检查这个集合的分片键是否倾斜,或者writeConcern是否设成了{w: "majority"}导致同步等待太久 -
mongotop --host <shard-primary-host>:<port></port></shard-primary-host>能按集合维度看读写耗时,比监控图早10分钟发现异常 - 有些场景下
iops_usage没红,但mem_usage持续90%+:说明WiredTiger cache反复淘汰,被迫频繁读盘——这其实是内存不足引发的间接I/O飙升,不是磁盘本身不够快
扩容前必须验证的三件事
加Shard不是加完就完事。MongoDB分片集群的扩容效果高度依赖数据重分布是否完成、元数据是否同步、客户端驱动是否兼容新拓扑。跳过验证步骤,很可能出现“扩了等于没扩”。
- 确认
sh.status()输出里所有chunk都已均衡:重点看balancer状态是否为Currently enabled: yes,以及各shard的chunks数量差是否小于5% - 检查config server副本集状态:
rs.status()里不能有STARTUP2或RECOVERING成员,否则mongos可能读不到最新路由表 - 验证应用连接串:如果用的是老版本Java Driver(loadBalanced=true或升级Driver
data_iops突然翻倍,但cpu_usage纹丝不动,八成是WiredTiger cache被挤出,开始疯狂读盘;又比如连接数没爆,但db.currentOp()里一堆waitingForLock,那根本不是扩容能解决的事。











