mongostat 无法监测 GridFS 文件级吞吐量,因其仅统计底层文档操作(如 insert/find),而 GridFS 将文件切分为 fs.chunks 小文档并存元数据于 fs.files,操作被拆解且不聚合为字节维度。

mongostat 无法直接监测 GridFS 的读写吞吐量,它只统计数据库级操作(如 insert、query、getmore),而 GridFS 实际由 fs.files 和 fs.chunks 两个集合协同完成,其 I/O 被拆解为大量小文档的增删查,mongostat 显示的数值与真实文件级吞吐严重脱节。
为什么 mongostat 看不到 GridFS 文件读写量
GridFS 不是单次操作一个文件,而是把一个文件切分成多个 255KB 左右的 fs.chunks 文档,并在 fs.files 中存一条元数据。上传 100MB 文件会触发约 400 次 insert(fs.chunks)+ 1 次 insert(fs.files);下载时则触发 1 次 find(fs.files)+ 约 400 次 find(fs.chunks)。mongostat 只计数这些底层文档操作,不聚合为“文件”或“字节”维度。
-
mongostat的query列包含所有find,无法区分是查业务集合还是fs.chunks - 没有字段反映传输字节数,
netIn/netOut是 TCP 层总量,混杂了协议开销、认证、心跳等 - 默认采样周期 1 秒,高频小文件场景下,
insert/query计数易抖动,难以对齐实际吞吐节奏
真正能反映 GridFS 吞吐的替代方案
要监控“每秒上传/下载多少 MB”,必须绕过 mongostat,在应用层或 MongoDB 服务端做字节级埋点:
- 在应用代码中,用
GridFSBucket.openUploadStream()/.openDownloadStream()包裹流式操作,用stream.on('data')累加Buffer.length,按秒上报 - 启用 MongoDB 的
system.profile(慢查询日志),设置slowms: 0,再用聚合管道筛选ns: /^mydb\.fs\.chunks$/的docsExamined和估算 chunk 大小(固定 255KB ×nreturned) - 用
mongotop --host localhost:27017查看实时集合级读写时间占比,fs.chunks若长期占read时间 >70%,说明 GridFS 是 I/O 瓶颈,但依然不给字节数
如果坚持用 mongostat,至少这样解读才有点参考价值
它不能告诉你吞吐,但能暴露 GridFS 是否引发异常负载模式:
- 观察
query和getmore是否持续高位(>500/s):暗示大量小 chunk 并发读,可能未启用maxPoolSize或连接复用不足 - 检查
insert和del比例:正常上传应 insert 多、del 少;若 del 频繁出现,可能是误删旧版本导致 chunk 清理风暴 - 对比
netIn和netOut:上传主导时netIn应明显高于netOut;若反常,可能客户端反复重试或元数据查询失败 - 加
-o参数输出 CSV,用awk '{print $1,$8,$9}'提取时间、query、insert列,做简单趋势图
真正需要字节吞吐监控时,别指望 mongostat——它连 fs.files 和 fs.chunks 的操作都混在一起,更不会知道你传的是视频还是缩略图。应用层流式计数是最轻量且准确的方式,而 MongoDB Atlas 用户可以直接看内置的 GridFS Operations 图表(仅限云服务)。


















