必须直接监控每个shard节点的data_iops和await,因mongos仅是无状态路由层,其netin/netout高低不能反映后端shard真实i/o压力;await持续>20ms、%util高、faults/s>100或%dirty>10%等指标组合才能准确定位i/o瓶颈根源。

直接看每个 Shard 节点的 data_iops 和 await,别只盯着 mongos 或监控大盘。
为什么不能只看 mongos 的 netIn/netOut
mongos 是无状态路由层,它的网络流量高 ≠ 某个 Shard 在扛 I/O 压力。netIn/netOut 差异大,往往只是客户端连接分布不均或查询没带分片键导致广播——真正吃磁盘的是后端 Shard。你看到某 Shard 的 iostat -x 1 中 await 持续 >20ms,那才是真实瓶颈信号。
- 用
db.currentOp({ secs_running: { "$gt": 5 } })连到每个 Shard 的 Primary 上,观察shard字段是否集中出现在某一个 - 检查
db.product.getShardDistribution()(替换product为实际集合名),确认数据分布是否和 I/O 热点匹配 - 阿里云控制台里“IOPS 使用率”在旧版分片集群中恒为 0,不可信;必须查
data_iops监控曲线并与规格页标注的“最大 IOPS”比对
怎么抓到真实的单 Shard I/O 毛刺
监控粒度太粗会漏掉瞬时打满。比如采集间隔是 60 秒,而一次批量写入在 200ms 内把 IOPS 拉到峰值,监控图上只会显示一个平滑的“1200”,完全掩盖问题。
- 在 Shard 节点上跑
iostat -x 1实时盯r_await、w_await、%util和await,重点关注后者是否持续 >10ms - 同时执行
mongostat --host <shard-primary-host>:27018 -n 1</shard-primary-host>,观察%dirty(>10% 表示 WiredTiger 缓存刷盘滞后)和faults/s(>100 表示工作集溢出内存,频繁缺页) - 用
lsblk -d -o NAME,ROTA确认数据盘是不是 HDD(ROTA=1),HDD 的await天然偏高,混部其他进程也会抬高该值
data_iops 高但业务没卡?先查压缩和 journal 配置
data_iops 高不一定代表业务吞吐高,可能是 WiredTiger 写入路径效率低导致的无效 I/O 放大。
- 检查
storage.wiredTiger.collectionConfig.blockCompressor:设为zlib会显著拖慢写入,snappy是默认且更平衡的选择 - 确认
storage.journal.enabled是否开启(生产环境必须开),但也要注意 journal 文件是否落在慢盘上 - 运行
mongotop --host <shard-primary>:27018 1</shard-primary>,看是不是某个集合(如orders)的 write 时间突增——这说明热点不在集群层面,而在具体集合设计或索引缺失
真正难判断的不是“哪个 Shard IO 高”,而是“为什么高”。await 高可能源于磁盘本身,也可能源于 WiredTiger 缓存压力或 CPU 不足;data_iops 接近上限时,要立刻区分是真实业务增长,还是脏页积压、缺页中断、低效压缩导致的 I/O 膨胀。这些细节藏在 mongostat 和 iostat 的交叉比对里,而不是监控图表的单一数值中。











