监控工具概述与权限配置
MongoDB 提供核心诊断工具 mongostat(服务器级资源监控)和 mongotop(集合级读写分析),用于实时追踪性能瓶颈
执行命令需 clusterMonitor 角色(仅授权监控接口访问,禁止数据修改)
权限配置流程
use admin
db.createUser({
user: "monitorUser",
pwd: "securePassword", # 通过环境变量注入更安全
roles: ["clusterMonitor"] # 关键权限!
# roles: [{ role: "clusterMonitor", db: "admin" }]
})
import { Injectable } from '@nestjs/common';
import { InjectModel } from '@nestjs/mongoose';
import { Model } from 'mongoose';
@Injectable()
export class UserService {
constructor(@InjectModel('User') private userModel: Model<any>) {}
async createMonitorUser() {
await this.userModel.create({
user: 'monitorUser',
pwd: process.env.MONITOR_PWD, // 环境变量注入
roles: [{ role: 'clusterMonitor', db: 'admin' }]
});
}
}
要点
- 用户必须在
admin库创建,覆盖集群级权限 - 生产环境需启用 TLS 加密连接
- 遵循最小权限原则,避免授予
find/insert等操作权
mongostat:实时数据库状态监控
1 )基础命令与输出解析
mongostat --host localhost:27017 \
-u monitorUser -p ${{MONITOR_PWD}} \
--authenticationDatabase admin
输出说明(每秒刷新):
| 字段 | 含义 | 故障阈值 |
|---|---|---|
command | 每秒执行的命令数 | 突增需排查慢查询 |
dirty | 缓存中待写入磁盘的数据比例 | >20% 预示 I/O 瓶颈 |
used | 缓存中活跃数据比例 | >90% 需扩容内存 |
vsize | 虚拟内存使用量 (MB) | 持续增长且 > 物理内存 200% = 内存泄漏风险 接近系统虚拟内存上限 = OOM 风险 |
res | 常驻内存使用量 (MB) | >70% 物理内存总量 = 预警 >90% 物理内存总量 = 紧急扩容 |
conn | 当前开放连接数 | 持续增长=连接泄漏 |
2 ) 参数定制化
| 参数 | 功能 | 示例命令 |
|---|---|---|
[间隔秒数] | 抓取频率调整 | mongostat ... 3 |
--rowcount | 限制抓取次数 | mongostat ... --rowcount 5 3 |
-o="字段列表" | 筛选输出字段 | mongostat -o="command,dirty,conn" ... |
每3秒采样,共5次,仅显示关键字段
mongostat -o "command,dirty,conn" 3 --rowcount 5 ...
输出JSON格式(适合自动化分析)
mongostat --json ...
3 )综合示例
mongostat 动态报告数据库进程的多维度状态指标。基础命令需指定连接参数:
mongostat --host localhost --port 27017 \
--username monitorUser --password securePassword \
--authenticationDatabase admin
关键特性与参数解析:
- 默认抓取频率:1 秒/次,输出包括
command(每秒命令数)、dirty(未刷新的缓存比例)、used(已使用缓存比例)、vsize(虚拟内存用量)、res(常驻内存用量)、conn(当前连接数)及time(时间戳)。 - 调整抓取频率:通过追加数字参数修改间隔(单位:秒)。例如,每 3 秒抓取:
mongostat --host localhost --port 27017 -u monitorUser -p securePassword --authenticationDatabase admin 3 - 限制报告次数:
--rowcount参数控制总抓取次数。以下命令每 3 秒抓取,共执行 5 次后自动终止:mongostat --host localhost --port 27017 -u monitorUser -p securePassword --authenticationDatabase admin 3 --rowcount 5 - 筛选输出字段:
-o参数指定需关注的指标(逗号分隔)。例如仅显示command、dirty、conn:
指标深度解析:mongostat -o "command,dirty,conn" --host localhost --port 27017 -u monitorUser -p securePassword --authenticationDatabase admindirty与used:诊断缓存健康度的核心参数。dirty表示待写入磁盘的缓存占比,过高可能预示 I/O 瓶颈;used反映缓存利用率,持续高位需警惕内存压力。conn:当前活跃连接数,突增可能暗示连接泄漏或负载激增
mongotop:集合级读写耗时分析
1 ) 基础命令与特性
mongotop --host localhost:27017 -u monitorUser ...
- 输出字段:
ns(集合命名空间)、read(读耗时/ms)、write(写耗时/ms) - 隐藏集合策略:仅显示最近活跃集合,可通过
db.collection.findOne()触发可见性
2 )参数扩展
每5秒采样,共8次
mongotop 5 --rowcount 8 ...
过滤特定数据库(如prod库)
mongotop --filter '{ "ns": "/^prod./" }'
3 )综合示例
mongotop 聚焦集合维度的读写操作时间分布,要求相同 clusterMonitor 权限。基础命令:
mongotop --host localhost --port 27017 \
--username monitorUser --password securePassword \
--authenticationDatabase admin
核心功能与调优:
- 活跃集合过滤:仅显示近期有操作的集合。若目标集合未出现,可通过触发操作(如
db.collection.findOne())激活监控。 - 调整抓取频率:追加数字参数修改间隔(如每 5 秒抓取):
mongotop --host localhost --port 27017 -u monitorUser -p securePassword --authenticationDatabase admin 5 - 限制报告次数:
--rowcount参数控制输出行数。以下命令每 5 秒抓取,共 5 次后终止:mongotop --host localhost --port 27017 -u monitorUser -p securePassword --authenticationDatabase admin 5 --rowcount 5
输出示例显示各集合的 read 和 write 耗时(毫秒),idle 表示无活动状态,适用于定位慢查询或负载不均问题。
NestJS 集成实战
1 ) 封装 mongostat 监控服务
import { Injectable, Logger } from '@nestjs/common';
import { exec } from 'child_process';
@Injectable()
export class MongoMonitorService {
private readonly logger = new Logger(MongoMonitorService.name);
async getMongoStat(interval: number): Promise<string> {
const command = `mongostat --json -o "conn,dirty,used" ${interval} --rowcount 1`;
return new Promise((resolve, reject) => {
exec(command, (error, stdout) => {
if (error) reject(`监控失败: ${error.message}`);
const { conn, dirty, used } = JSON.parse(stdout);
// 动态阈值告警
if (dirty > 20) this.logger.warn(`脏缓存过高: ${dirty}%`);
resolve(`连接数: ${conn}, 缓存使用率: ${used}%`);
});
});
}
}
或
// NestJS 服务层代码:获取 mongostat 指标
import { Injectable, Logger } from '@nestjs/common';
import { exec } from 'child_process';
@Injectable()
export class MongoMonitorService {
private readonly logger = new Logger(MongoMonitorService.name);
async getMongoStat(): Promise<string> {
const command = `mongostat --host localhost:27017 -u monitorUser -p securePassword --authenticationDatabase admin -o "conn,dirty,used" --rowcount 1 --noheaders`;
return new Promise((resolve, reject) => {
exec(command, (error, stdout) => {
if (error) reject(`监控失败: ${error.message}`);
const [conn, dirty, used] = stdout.split(/\s+/).filter(Boolean);
resolve(`当前连接数: ${conn}, 脏数据比例: ${dirty}%, 缓存使用率: ${used}%`);
});
});
}
}
2 ) 自动诊断集合读写延迟,封装 mongotop
async checkCollectionLatency(collectionName: string): Promise<void> {
const command = `mongotop --json 5 --rowcount 1`;
exec(command, (error, stdout) => {
const data = JSON.parse(stdout);
const target = data.find((item: any) => item.ns.includes(collectionName));
if (target && (target.read > 100 || target.write > 200)) {
this.logger.error(`集合 ${collectionName} 延迟异常!读: ${target.read}ms, 写: ${target.write}ms`);
}
});
}
或
// 检测集合读写超时
async checkCollectionLatency(collectionName: string): Promise<void> {
const command = `mongotop --host localhost:27017 -u monitorUser -p securePassword --authenticationDatabase admin 5 --rowcount 1`;
exec(command, (error, stdout) => {
const lines = stdout.split('\n');
const targetLine = lines.find(line => line.includes(collectionName));
if (targetLine) {
const [, , readMs, writeMs] = targetLine.split(/\s+/);
if (parseInt(readMs) > 100 || parseInt(writeMs) > 200) {
this.logger.warn(`集合 ${collectionName} 读写延迟过高!读: ${readMs}ms, 写: ${writeMs}ms`);
}
}
});
}
要点
- 密码必须通过
process.env注入,禁止硬编码 - 高频监控(间隔<5秒)可能增加服务负载
- JSON 输出便于整合 Prometheus/Grafana
3 ) 通过 child_process 模块调用 mongostat,实现自定义监控逻辑:
import { Injectable } from '@nestjs/common';
import { exec } from 'child_process';
@Injectable()
export class MongoDBMonitorService {
async runMongostat(interval: number, rowCount: number): Promise<string> {
return new Promise((resolve, reject) => {
const command = `mongostat --host localhost --port 27017 \
-u monitorUser -p securePassword \
--authenticationDatabase admin \
${interval} --rowcount ${rowCount}`;
exec(command, (error, stdout, stderr) => {
if (error) reject(`监控失败: ${error.message}`);
if (stderr) reject(`错误输出: ${stderr}`);
resolve(stdout);
});
});
}
}
// 控制器调用示例
import { Controller, Get } from '@nestjs/common';
import { MongoDBMonitorService } from './monitor.service';
@Controller('monitor')
export class MonitorController {
constructor(private readonly monitorService: MongoDBMonitorService) {}
@Get('stat')
async getMongoStat() {
return this.monitorService.runMongostat(3, 5); // 每3秒抓取,共5次
}
}
关键补充知识点:
- 安全增强:密码应通过环境变量注入(如
process.env.MONGO_PWD),避免硬编码。 - 错误处理:捕获
ECONNREFUSED异常以处理数据库连接失败场景。 - 性能影响:高频监控可能增加服务器负载,建议生产环境间隔 ≥5 秒。
故障诊断与核心指标解析
1 ) 缓存机制工作原理
2 ) 关键故障场景对照表
| 现象 | 诊断命令 | 解决方案 |
|---|---|---|
dirty 持续 >20% | db.serverStatus().wiredTiger | 优化磁盘 I/O 或调整刷盘间隔 |
conn 异常增长 | db.currentOp() | 检查连接池泄漏或 DDoS 攻击,检查连接池配置 |
mongotop 无目标集合 | db.collection.stats() | 触发 findOne() 激活监控 |
command突增 | db.system.profile.find()db.currentOp()db.getProfilingStatus() | 分析慢日志 |
dirty与used的故障关联:dirty持续 >20%:可能因磁盘 I/O 延迟导致写入堆积,需检查存储性能used接近 100%:表明缓存饱和,易引发查询性能下降,需扩容内存或优化索引
- 连接数 (
conn) 突增对策:db.currentOp() // 查看活跃操作 db.serverStatus().connections // 分析连接来源 mongotop零读写场景:若集合无操作,可通过db.collection.stats()验证活跃度
3 ) 性能优化建议
- 写入堆积:当
dirty超标时,调整 WiredTiger 引擎配置:wiredTiger: engineConfig: checkpoint: (size=2GB, wait=60s) # 增加刷盘触发阈值 - 内存压力:
used接近 100% 时:- 扩容 RAM 或启用
zstd压缩 - 分析
db.runCommand({top:1})定位高消耗集合
- 扩容 RAM 或启用
构建高效监控体系
1 ) 工具定位对比
| 工具 | 监控层级 | 核心指标 | 适用场景 |
|---|---|---|---|
mongostat | 服务器进程级 | dirty/used/conn | 资源饱和预警 |
mongotop | 集合操作级 | read/write 延迟 | 慢查询定位 |
2 ) 最佳实践总结
- 权限最小化:严格限制
clusterMonitor角色范围 - 参数动态化:生产环境采样间隔 ≥5 秒,开发环境可放宽
- 诊断闭环:阈值告警 → 日志分析 → 引擎调优
- 自动化整合:通过 JSON 输出对接 CI/CD 流水线
3 )引擎缓存工作原理
4 ) 扩展建议
- 结合
explain()分析慢查询执行计划 - 集成 Ops Manager 实现监控可视化
- 定期审计
system.roles防止权限扩散
监控的本质是预判故障而非事后补救。掌握 mongostat/mongotop 的黄金指标(dirty/used/conn/latency),可构建 MongoDB 性能的“免疫系统”
关键知识点补充
-
监控角色权限:
clusterMonitor角色包含serverStatus、top等权限,禁止find或insert。- 生产环境需通过 TLS 加密连接传输监控数据。
-
引擎缓存机制:
- WiredTiger 缓存:
dirty表示待刷写数据,used表示缓存利用率。 - 优化建议:当
dirty持续 >30%,需增加磁盘 I/O 或调整wiredTigerEngineConfig。
- WiredTiger 缓存:
-
原生命令扩展参数:
# 输出 JSON 格式(适用于自动化分析) mongostat --json -u monitorUser -p securePassword # 过滤特定数据库 mongotop --host localhost:27017 --filter '{ "ns": "/^prod./" }'
总结
通过 mongostat 和 mongotop 的组合使用,可实现:
- 实时性能分析:服务器进程级资源消耗监控
- 瓶颈定位:集合粒度读写操作耗时统计
- 动态调控:通过频率/次数参数适配不同监控场景
- 故障预警:基于
dirty/used等核心指标预判引擎状态异常
关键提示:所有监控操作必须严格遵循最小权限原则,仅授予 clusterMonitor 角色权限以避免安全风险
mongostat 聚焦服务器级资源指标(内存/连接/命令),mongotop 定位集合级读写瓶颈。通过 动态参数调整、关键指标筛选 及 自动化集成,可构建高效监控体系
权限配置需严格遵循最小特权原则,并结合缓存指标 (dirty/used) 预判 I/O 风险
1171



被折叠的 条评论
为什么被折叠?



