广告位 · 页头(后台-模块管理-新建模块后替换此区域)

如何用 mongostat 实时监控 MongoDB 数据库运行状态?

当 MongoDB 出现响应变慢时,很多第一反应是查看慢查询日志,但慢日志只能说明某条语句执行时间长,无法直接反映实例整体的连接压力、内存换页和操作队列变化。mongostat 是 MongoDB 自带的一个轻量级状态监控工具,它以类似 Linux vmstat 的方式每秒输出一行统计,能够快速帮助运维和开发人员判断数据库当前是读多写少、连接打满、还是内存不足。该工具随 mongodb-database-tools 或服务器二进制包一起提供,通常位于 MongoDB 安装目录的 bin 下。

如何用 mongostat 实时监控 MongoDB 数据库运行状态?

启动 mongostat 最基本的命令是直接执行 mongostat,默认连接本机 27017 端口的 mongod 或 mongos。如果实例在远程主机,可以加上 --host 参数。下面先给出一段默认输出示例,帮助理解后续字段说明。

insert query update delete getmore command dirty  used flushes vsize   res qr qw ar aw netIn netOut conn time
    *0    *0     *0     *0       0     1|0  0.2% 75.2%       0 1.50G 203M  0  0  0  0  1.2k   4.5k   10 10:15:30
    *1    *2     *0     *0       0     2|0  0.2% 75.2%       0 1.50G 203M  0  0  0  0  3.8k   7.2k   10 10:15:31

输出中每行对应一个采样周期,默认一秒一次。以 * 开头表明当前值是采样间隔内的变化量,而不是累计值;带 | 的字段表示读写命令的成功与失败次数。这张输出表本身就能回答很多问题:如果 qr 或 ar 持续大于 0,说明读操作在排队;如果 conn 逐步逼近实例配置的 maxIncomingConnections,连接层可能先成为瓶颈。

mongostat 核心指标怎么读

默认输出的字段比较多,但可以分成操作计数、内存与存储、队列与连接、网络吞吐四组。操作计数包括 insert、query、update、delete、getmore 和 command,它们表示每秒执行的各类操作数量。getmore 专门指客户端从游标继续拉取数据,比如批量遍历集合时会出现。command 字段的 1|0 形式表示成功一次、失败零次。持续观察这些数值可以判断业务读写比例,例如 query 远大于 insert 的实例通常偏向检索型场景,而 update 频繁则要考虑写入放大和索引维护成本。

内存相关字段中,dirty 是 WiredTiger 缓存中尚未刷盘的脏数据百分比,used 是缓存使用百分比。默认配置下 WiredTiger 缓存大小为物理内存的一半减去 1GB,如果 used 长期接近 100% 且 dirty 较高,说明缓存压力大,可能出现数据频繁从磁盘读取。这时可以结合 vsize 和 res 来看:vsize 是进程虚拟内存大小,res 是实际驻留内存大小。res 接近物理内存上限时,操作系统可能开始换页,性能会明显下降。flushes 表示每秒钟执行的 fsync 次数,写多时该值会上升。

队列字段 qr 和 qw 表示等待读取或写入的客户端队列长度,ar 和 aw 是活跃执行读或写操作的数量。如果 qr 持续大于 0,而 ar 并不高,通常说明有读操作被锁或磁盘 IO 阻塞;如果 qw 积压且 aw 已经接近并发上限,则要考虑扩容或优化写模式。网络字段 netIn 和 netOut 统计每秒网络输入输出字节数,单位是 KB 或 MB,可以帮助区分是网络带宽打满还是磁盘吞吐不足。

最后 conn 是当前连接数,注意这是实例级别的连接总数,而不是应用连接池中的客户端数量。连接数瞬间飙升可能会触发 MongoDB 的拒绝服务保护,因此监控该值的变化趋势比单点数值更重要。

常用启动参数与输出控制

直接运行 mongostat 会持续不断输出,对于脚本采集或者只看最近几十行的情况并不方便。可以使用 --rowcount 参数限制输出行数,例如只采样 20 次后自动退出,适合定时任务抓取快照。命令如下:

mongostat --rowcount=20 --host=127.0.0.1 --port=27017

如果 mongod 开启了认证,需要加上 --username、--password 和 --authenticationDatabase 参数。实际使用中不建议在命令行明文写密码,可以通过环境变量或提示输入的方式提供。连接副本集时,使用 --host 传入副本集名称和成员地址,格式为 replSetName/host1:port1,host2:port2,mongostat 会从返回的成员中读取数据。连接分片集群时通常连接 mongos 进程,因为 mongos 会聚合各个分片的统计信息。

另一个实用参数是 --discover,它会在副本集模式下自动发现所有节点,并把每个节点的统计并排显示出来。对于需要观察主从延迟和读写分布的场景非常有用。输出会多出 host 列,标识每行来自哪个成员。配合 --noheaders 可以去掉表头,方便把输出重定向到文本文件后用脚本解析。例如:

mongostat --host=rs0/192.168.1.10:27017,192.168.1.11:27017 --discover --rowcount=10 --noheaders

还有一些与 MongoDB 服务器版本相关的细节:从 4.4 开始,mongostat 输出的 dirty 和 used 字段只适用于使用 WiredTiger 存储引擎的实例,如果使用内存存储引擎或老版本 MMAPv1,这些列可能显示为 0 或不出现。对于 5.0 及以上版本,部分字段名称保持不变,但内部统计口径可能微调,因此排查问题时最好先确认客户端工具版本与服务器版本是否匹配。如果 mongostat 版本过老,连接新版本 MongoDB 时可能无法识别部分新指标,建议使用与服务器相同大版本的工具包。

结合系统指标定位性能瓶颈

mongostat 反映的是数据库内部视角,要完整定位问题还需要结合操作系统指标。一个常见误区是看到 query 很高就认为慢查询多,实际上 query 只是计数,不代表查询是否走索引、是否扫描大量文档。真正需要关注的是结合 qr 和 ar 判断有没有排队,以及结合 MongoDB 日志中的 slow query 确定具体语句。例如下面这个组合命令:

mongostat --rowcount=30 --host=127.0.0.1 > mongostat_$(date +%F_%H%M%S).log
tail -n 10 mongostat_*.log

该命令把 30 秒的采样结果写入带时间戳的日志文件,然后查看最近 10 行,适合在问题复现时快速抓取现场。看完之后可以检查同一时间段内的系统 CPU、磁盘 IO 和内存。Linux 下可用 iostat -x 1 查看磁盘平均等待时间,如果 await 持续超过 20 毫秒,同时 mongostat 中 qr 或 qw 不为零,基本可以判断磁盘成为瓶颈。此时扩容磁盘、增加缓存或调整写入关注级别都能缓解。

另一个典型问题是连接数增长异常。应用如果使用连接池,理论上连接数应该平稳,但若有连接泄漏,conn 会持续上涨,最终逼近上限后新的请求无法建立连接。可以用 mongostat 的 --json 参数输出 JSON 格式,配合 jq 或脚本定时解析 conn 字段,设置阈值告警。例如:

mongostat --rowcount=1 --host=127.0.0.1 --json

输出为一个 JSON 对象,包含所有字段,脚本可以通过 jq '.conn' 提取当前连接数。虽然 mongostat 本身没有内置告警,但作为数据源接入监控系统非常方便。

mongostat 与 mongotop 的适用边界

有些用户会把 mongostat 和 mongotop 混用,其实两者定位不同。mongostat 展示的是实例级操作计数、内存、网络和队列,适合判断整体健康状态;mongotop 则按集合或命名空间展示读写耗时,适合找出具体哪个集合读写最频繁。如果业务整体变慢,先用 mongostat 看是否存在全局性资源争用;如果只有某个接口慢,再用 mongotop 定位到具体集合,最后用 explain 分析对应查询。

实际排障中可以按顺序执行:先运行 mongostat --rowcount=60 观察一分钟,重点关注 conn、qr、qw、dirty、used 和 netIn、netOut;发现队列长时间堆积后运行 mongotop 查看是哪个集合占用了时间;最后对相关查询执行 explain(executionStats) 检查索引使用情况。这种从整体到局部的方式,比直接猜测某条慢查询更可靠。

最后要提醒的是,mongostat 本身也会产生少量数据库连接和命令开销,虽然非常小,但在极端性能测试中最好把采样间隔调大或使用 --rowcount 控制时长,避免监控工具干扰结果。日常巡检中建议把它和 MongoDB Cloud Manager、Prometheus 等监控体系结合使用,让 mongostat 作为命令行快速排查的补充手段,而不是唯一的监控来源。

广告位 · 文章底部(后台-模块管理替换此区域)