外观
MongoDB 服务器状态指标
内存指标
系统内存使用
指标路径:db.serverStatus().mem
关键指标:
resident:MongoDB 进程实际使用的物理内存(MB)virtual:MongoDB 进程使用的虚拟内存(MB)mapped:映射到内存的数据文件大小(MB)mappedWithJournal:包括日志文件在内的映射大小(MB)
解读与最佳实践:
resident通常不应超过系统可用内存的 80%- 如果
virtual远大于resident,可能存在内存泄漏 mapped大小应与数据文件大小相符
示例:
javascript
// 查看内存使用情况
const memStats = db.serverStatus().mem;
print(`物理内存使用: ${memStats.resident} MB`);
print(`虚拟内存使用: ${memStats.virtual} MB`);WiredTiger 缓存状态
指标路径:db.serverStatus().wiredTiger.cache
关键指标:
bytes currently in the cache:当前缓存中的字节数maximum bytes configured:缓存配置的最大字节数bytes read into cache:从磁盘读取到缓存的字节数bytes written from cache:从缓存写入到磁盘的字节数pages evicted by application threads:应用线程驱逐的页面数unmodified pages evicted:未修改页面驱逐数modified pages evicted:修改页面驱逐数
解读与最佳实践:
- 缓存使用率(current/maximum)应保持在 80-90% 之间
- 过高的驱逐率(evicted pages)可能表示缓存不足
- 如果
modified pages evicted持续增长,可能存在磁盘 I/O 瓶颈
示例:
javascript
// 查看 WiredTiger 缓存状态
const cacheStats = db.serverStatus().wiredTiger.cache;
const usagePercent = (cacheStats["bytes currently in the cache"] / cacheStats["maximum bytes configured"]) * 100;
print(`WiredTiger 缓存使用率: ${usagePercent.toFixed(2)}%`);连接指标
连接统计
指标路径:db.serverStatus().connections
关键指标:
current:当前活跃连接数available:可用连接数totalCreated:自实例启动以来创建的连接总数
解读与最佳实践:
current应远低于配置的最大连接数(默认 65536)- 持续增长的
totalCreated可能表示连接泄漏 - 设置合理的连接超时时间,避免空闲连接占用资源
示例:
javascript
// 查看连接状态
const connStats = db.serverStatus().connections;
print(`当前连接数: ${connStats.current}`);
print(`可用连接数: ${connStats.available}`);
print(`总连接创建数: ${connStats.totalCreated}`);操作统计指标
操作计数器
指标路径:db.serverStatus().opcounters
关键指标:
insert:插入操作总数query:查询操作总数update:更新操作总数delete:删除操作总数getmore:getMore 操作总数(用于游标)command:命令操作总数
解读与最佳实践:
- 监控操作类型分布,了解业务特点
- 突然的操作数增长可能表示异常流量
- 结合时间窗口计算每秒操作数(OPS)
示例:
javascript
// 查看操作统计
const opStats = db.serverStatus().opcounters;
print(`总插入操作: ${opStats.insert}`);
print(`总查询操作: ${opStats.query}`);
print(`总更新操作: ${opStats.update}`);
print(`总删除操作: ${opStats.delete}`);操作计数器详情
指标路径:db.serverStatus().opcountersRepl
关键指标:
- 副本集成员间复制操作的计数,包括 insert、query、update、delete 等
解读与最佳实践:
- 比较主节点和副本节点的操作计数器,检查复制延迟
- 异常的复制操作计数可能表示复制问题
存储指标
存储引擎状态
指标路径:db.serverStatus().storageEngine
关键指标:
name:存储引擎名称(如 WiredTiger)supportsCommittedReads:是否支持已提交读readOnly:是否为只读模式
解读与最佳实践:
- 确认使用的存储引擎符合预期
- 检查是否支持所需的功能
数据文件状态
指标路径:db.serverStatus().metrics.document
关键指标:
deleted:删除的文档数inserted:插入的文档数returned:查询返回的文档数updated:更新的文档数
解读与最佳实践:
- 监控文档操作频率,了解数据变化趋势
- 结合其他指标分析数据增长情况
锁定指标
全局锁定状态
指标路径:db.serverStatus().globalLock
关键指标:
totalTime:自实例启动以来的总锁定时间(微秒)currentQueue:当前等待锁定的操作队列read:读操作等待队列长度write:写操作等待队列长度
activeClients:当前活跃客户端read:活跃读客户端数write:活跃写客户端数
解读与最佳实践:
currentQueue.read或currentQueue.write持续增长表示锁竞争严重- 高锁等待时间可能导致性能下降
- 优化慢查询和索引设计,减少锁持有时间
示例:
javascript
// 查看全局锁定状态
const lockStats = db.serverStatus().globalLock;
print(`读操作等待队列: ${lockStats.currentQueue.read}`);
print(`写操作等待队列: ${lockStats.currentQueue.write}`);数据库级锁定
指标路径:db.serverStatus().locks
关键指标:
- 按数据库和集合分类的锁定统计
- 包括锁定类型(R、W、r、w)和等待时间
解读与最佳实践:
- 识别锁定热点数据库和集合
- 优化热点集合的查询和更新操作
- 考虑分片分散负载
复制集指标
复制集状态
指标路径:db.serverStatus().repl
关键指标:
ismaster:是否为主节点secondary:是否为副本节点arbiters:仲裁节点列表hosts:所有节点列表primary:主节点地址me:当前节点地址
解读与最佳实践:
- 确认当前节点角色符合预期
- 检查复制集成员状态
复制延迟指标
指标路径:db.serverStatus().repl
关键指标:
optimeDate:当前操作时间戳- 结合
rs.status()查看各节点的lastHeartbeat和lastHeartbeatRecv
解读与最佳实践:
- 监控复制延迟,确保数据及时同步
- 复制延迟过大可能影响灾备能力
示例:
javascript
// 查看复制集状态
const replStats = db.serverStatus().repl;
print(`是否为主节点: ${replStats.ismaster}`);
print(`是否为副本节点: ${replStats.secondary}`);
print(`主节点地址: ${replStats.primary}`);网络指标
网络 I/O 统计
指标路径:db.serverStatus().network
关键指标:
bytesIn:接收的字节数bytesOut:发送的字节数numRequests:处理的请求数
解读与最佳实践:
- 监控网络流量,了解数据传输情况
- 突然的流量变化可能表示异常
- 结合操作计数分析网络效率
示例:
javascript
// 查看网络统计
const netStats = db.serverStatus().network;
print(`总接收字节数: ${netStats.bytesIn}`);
print(`总发送字节数: ${netStats.bytesOut}`);
print(`总请求数: ${netStats.numRequests}`);日志指标
日志记录统计
指标路径:db.serverStatus().metrics.log
关键指标:
global:全局日志统计operations:日志操作数latency:日志写入延迟
解读与最佳实践:
- 监控日志写入性能,避免日志成为瓶颈
- 调整日志级别,平衡日志详细程度和性能
指标监控最佳实践
1. 建立基线
- 在系统正常运行时收集指标,建立性能基线
- 定期更新基线,适应业务变化
- 对比当前指标与基线,识别异常
2. 设置合理的告警阈值
- 内存使用率 > 85%
- 连接数 > 70% 最大连接数
- 锁等待队列长度持续 > 10
- 复制延迟 > 30 秒
- 磁盘使用率 > 80%
3. 综合分析指标
- 单一指标异常可能不代表问题,需要综合分析
- 例如:高 CPU 使用率 + 高锁等待 = 锁竞争问题
- 高内存使用率 + 高驱逐率 = 缓存不足
4. 定期监控
- 实时监控:使用 mongostat、mongotop 等工具
- 历史监控:使用 MongoDB Atlas、Ops Manager 或 Prometheus + Grafana
- 日志分析:定期分析慢查询日志和系统日志
5. 优化基于指标
- 根据指标分析结果进行针对性优化
- 优化索引、查询、配置参数或硬件资源
- 优化后重新评估指标,验证优化效果
常见问题(FAQ)
Q1: 如何计算 MongoDB 每秒操作数(OPS)?
A1: 可以通过比较不同时间点的 opcounters 差值除以时间间隔来计算:
javascript
// 在时间 t1 记录操作计数
const t1 = new Date();
const opcounters1 = db.serverStatus().opcounters;
// 等待一段时间后再次记录
sleep(1000); // 等待 1 秒
const t2 = new Date();
const opcounters2 = db.serverStatus().opcounters;
// 计算每秒操作数
const timeDiff = (t2 - t1) / 1000;
const totalOps1 = opcounters1.insert + opcounters1.query + opcounters1.update + opcounters1.delete;
const totalOps2 = opcounters2.insert + opcounters2.query + opcounters2.update + opcounters2.delete;
const opsPerSecond = (totalOps2 - totalOps1) / timeDiff;
print(`每秒操作数: ${opsPerSecond.toFixed(2)}`);Q2: WiredTiger 缓存使用率过高怎么办?
A2: 可以通过以下方式解决:
- 增加系统内存
- 调整
storage.wiredTiger.engineConfig.cacheSizeGB参数 - 优化查询,减少缓存使用
- 考虑分片,分散缓存压力
Q3: 如何监控 MongoDB 磁盘 I/O?
A3: 可以使用以下方法:
iostat命令(系统级)db.serverStatus().wiredTiger.cache中的读写统计- MongoDB Atlas 或 Ops Manager 中的磁盘 I/O 指标
- 监控
db.serverStatus().network中的字节传输
Q4: 连接数持续增长怎么办?
A4: 可能的原因和解决方案:
- 应用程序连接泄漏:检查连接池配置,确保正确关闭连接
- 短连接过多:使用连接池,增加连接复用
- 配置问题:调整
maxIncomingConnections参数 - 考虑分片:分散连接到多个服务器
Q5: 如何区分正常和异常的指标值?
A5: 建立基线是关键。在系统正常运行时收集指标,了解正常范围。当指标超出基线 20-30% 时,需要进一步分析。同时,结合多个指标进行综合判断,单一指标异常可能不代表问题。
