reshardCollection本质是三路并发I/O(读旧分片、写新分片、刷WiredTiger日志),若journal与data共用物理盘,IOPS易打满导致卡死;需分离存储、启用高效压缩、合理设置migration线程数。

reshardCollection 本质是三路并发I/O,不是“复制”那么简单
它一边从旧分片读 chunk(read),一边往新分片写数据(write),一边还要刷 WiredTiger journal(journal flush)。这三类 I/O 全部挤在同一块物理盘上时,IOPS 很快打满——尤其是机械盘或低配 SSD,%util 持续 >95% 就是典型卡死信号。
常见错误现象:
- 进度长期卡在 37%、62% 等固定值
-
currentOp中大量操作状态为waitingForFlowControl或waitingForLock -
iostat -x 1显示await飙高、r/s和w/s同时密集波动
实操建议:
- SSD 随机写 IOPS 必须 ≥ 3000;NVMe 建议 ≥ 10000;机械盘不建议执行
reshardCollection - 把 journal、data、log 分到不同物理设备(如
/data、/journal、/logs各挂独立 SSD) - 确认
storage.wiredTiger.engineConfig.journalCompressor已设为snappy或zstd,避免压缩拖慢刷盘
reshardingNumMigrationThreads 调高反而让 I/O 更糟?
线程数增加 ≠ 吞吐线性提升。5.0.21+/6.0.14+ 支持调高 reshardingNumMigrationThreads,但前提是磁盘能扛住并发压力。若未满足 IOPS 硬性门槛,4 个线程可能比 1 个更早触发 waitingForFlowControl。
关键判断点:
- 调参前必须先跑
iostat -x 1观察 baseline:空载时%util是否已 >70% - 所有 mongod(含 config server)都需执行
db.adminCommand({ setParameter: 1, reshardingNumMigrationThreads: 4 }),漏一个就无效 - 该参数只能在
reshardCollection启动前设置,运行中修改不生效
为什么加了 SSD 还卡在 I/O?可能是 journal 和 data 共盘
WiredTiger 的 journal 刷盘是强制同步行为,哪怕你关了 journal: false,resharding 过程中也会被强制启用。如果 journal 文件和数据文件都在同一块 NVMe 上,write + journal flush 会互相抢占带宽。
检查方式:
- 查
mongod启动参数:--dbpath /data和--journal --journalDirectory /data/journal是危险组合 - 用
lsof -p $(pgrep mongod) | grep journal确认 journal 路径是否独立 - 生产环境推荐:journal 单独挂高速 NVMe,data 盘用大容量 SATA SSD
真正容易被忽略的点:resharding 不只压数据盘,它对 journal 设备的随机写压力比普通写入高 3–5 倍,而多数人只盯着 df -h 和 iostat 的 data 分区。


















