在MongoDB运维过程中,数据库整体负载不高但局部延迟陡增的情况十分常见。此时我们需要一个能够深入到集合级别的工具来观察到底是哪张表在被频繁读写。mongotop 就是MongoDB发行包中提供的一个命令行工具,它专门用于报告每个集合在采样周期内花费在读取和写入上的时间,从而让运维人员快速识别读写热点。

mongotop的基本用法与核心参数
mongotop 默认连接本机27017端口,每隔一秒输出一次各命名空间的读写时间统计。最直接的使用方式就是在终端执行 mongotop,它会持续刷新屏幕,类似于 Linux 下的 top 命令。如果你希望只查看一次结果,可以加上 --once 参数,这在编写监控脚本时非常有用。
除了基础连接,mongotop 还支持通过 --host、--port、--username 和 --password 来连接开启了鉴权的远程实例。例如 mongotop --host 192.168.0.1 --port 27017 -u admin -p secret --authenticationDatabase admin 可以安全地接入生产环境。需要注意的是,当 MongoDB 启用了 TLS 时,还要附加 --ssl 及相关证书路径,否则工具会拒绝连接。
另一个实用参数是 --locks,加上它之后工具会显示数据库级别的锁占用情况,而不仅仅是集合读写时间。在 MongoDB 3.0 之后的 WiredTiger 存储引擎下,锁的竞争往往体现在表级或文档级,因此结合普通模式与 --locks 模式对比,能更清楚判断瓶颈来自 IO 还是并发控制。
# 每2秒采样一次,共采样5次 mongotop 2 5 # 只输出一次结果,便于脚本解析 mongotop --once # 连接远程并指定鉴权库 mongotop --host 192.168.0.1 --port 27017 -u admin -p secret --authenticationDatabase admin
输出字段详解与热点识别逻辑
在默认输出中,每一行代表一个命名空间(如 test.users),主要有 ns、total、read、write 和 time 几个字段。read 和 write 分别表示该周期内读操作和写操作消耗的毫秒数,total 是二者之和,time 则是采样窗口长度。如果某个集合的 read 值长期接近 time,说明它几乎占满了采样期的读取能力,是典型的读热点。
识别写热点时,重点观察 write 列。在日志型或计数型业务中,单一集合被高频更新会导致 write 时间居高不下,进而引发全局刷盘延迟。此时若 mongotop 显示某集合写时间占比超过70%,就应检查是否缺少合适的分片键,或者是否可以把部分计数逻辑异步化。
对于多租户系统,不同业务表可能共用一个实例。通过 mongotop 的持续观察,能够发现某些低频业务在某个时间点突增读写,挤压了核心业务的资源。这种跨集合的资源争用,仅靠 mongostat 的全局指标是无法察觉的,必须依赖集合粒度的 mongotop 数据来归因。
ns total read write time test.users 1023ms 980ms 43ms 1000ms test.orders 312ms 10ms 302ms 1000ms local.oplog.rs 45ms 45ms 0ms 1000ms
与生产监控和慢查询的联动实践
单纯看 mongotop 的实时界面适合人工排查,但在常态化运维中,我们通常会将它的输出重定向到文件,再用脚本提取异常行。例如通过 mongotop --once | grep -E 'users|orders' 定时抓取核心表数据,当 read 或 write 超过阈值时触发告警。这种方式比部署重量级 APM 更轻量,也更容易嵌入现有 Shell 监控体系。
当 mongotop 定位到热点集合后,下一步应结合 MongoDB 的慢查询日志(system.profile 集合或日志文件中的 command 记录)分析具体语句。很多时候读写时间长并不是因为量大,而是因为缺少索引导致全表扫描。此时在热点集合上建立复合索引,往往能让 mongotop 中的 read 时间下降一个数量级。
在分片集群中,mongotop 需要在每个分片节点上分别执行,或者借助 mongos 的聚合管道汇总。如果某个分片的某集合明显比其它分片更热,说明分片键分布不均,需要考虑重新选择哈希分片或范围分片策略。通过这种从工具观测到架构调整的闭环,才能够从根本上解决读写热点问题,而不是临时扩容了事。
// 在 mongo shell 中查看慢查询聚集结果
db.system.profile.aggregate([
{ $match: { ns: 'test.users' } },
{ $group: { _id: '$op', avgMillis: { $avg: '$millis' }, count: { $sum: 1 } } },
{ $sort: { avgMillis: -1 } }
])
通过上述多维度使用 mongotop,开发者和 DBA 可以在不引入复杂监控栈的前提下,清晰掌握 MongoDB 内部集合级别的读写分布,并据此做出索引优化、分片调整或业务改造的决策。