GridFS本身不暴露IOPS指标,监控必须落到存储层;其文件分块写入会放大底层IOPS压力,需重点监控WiredTiger缓存、journal延迟、磁盘队列深度及节点级r/s、w/s值,并通过带节点标签的Prometheus+Grafana实现精准瓶颈定位。

GridFS本身不暴露IOPS指标,监控必须落到存储层
GridFS是逻辑抽象层,它把文件拆成fs.chunks和fs.files两个集合存进WiredTiger引擎,实际I/O压力全部由底层存储引擎和磁盘承担。你直接在MongoDB里查db.serverStatus()或mongostat,根本看不到“GridFS读写次数”或“chunk块IO吞吐”这类指标——这些压根不存在。真正要盯的是WiredTiger缓存刷盘频率、磁盘队列深度、每秒随机读写数(IOPS),以及这些指标在副本集各节点上的分布差异。
关键采集点:WiredTiger journal + Linux block device stats
在分布式部署(如3节点副本集或分片集群)中,GridFS文件写入会先落journal,再刷到data目录下的.wt文件。这意味着IOPS热点集中在:
-
/var/lib/mongodb/journal/目录的写入延迟(尤其主节点写密集时) -
/var/lib/mongodb/下所有*.wt文件的随机读(GridFS流式读取触发大量小块读) - 每个节点挂载的PV(如CephFS或云盘)的
await、avgqu-sz、r/s、w/s值
用iostat -x 1在每个mongod宿主机上实测,重点关注r/s和w/s是否持续超过磁盘标称IOPS(比如AWS gp3标称3000 IOPS,但实际w/s长期>2500就该预警)。
Prometheus抓取时必须加节点维度标签
如果你用mongodb_exporter,默认只暴露全局指标,对GridFS无意义。必须手动注入节点身份,否则无法区分是主节点扛住了写压力,还是某个副本节点因磁盘慢导致复制延迟飙升。配置示例:
scrape_configs:
- job_name: 'mongodb-gridfs-iops'
static_configs:
- targets: ['mongod-0:9216', 'mongod-1:9216', 'mongod-2:9216']
labels:
instance: 'mongod-0'
role: 'primary'
- targets: ['mongod-1:9216']
labels:
instance: 'mongod-1'
role: 'secondary'
# ……
然后在Grafana里按instance或role切片,叠加node_disk_io_time_seconds_total(来自node_exporter)和mongodb_mongod_wt_cache_dirty_bytes(来自mongodb_exporter),才能看出“哪个节点的脏页堆积+磁盘响应慢”这个典型GridFS写瓶颈链路。
容易被忽略的隐性放大点:GridFS chunkSize与IOPS的非线性关系
GridFS默认chunkSize是255 KiB,但一个100 MiB视频上传会生成约400个chunk文档。每次put操作实际触发400次独立的WiredTiger写入,且这些写入是并发刷journal的。结果就是:逻辑上1次文件上传 → 物理上400次随机小写 → IOPS被放大数百倍。如果你发现w/s异常高但业务QPS很低,八成是chunkSize设得太小。调大到1 MiB(需驱动层支持),chunk数量减少75%,IOPS压力直降。但注意:改chunkSize后旧文件不会自动迁移,新旧混合场景下监控曲线会出现双峰。











