3. 监控数据采集机制与工具选型

MongoDB 的监控数据来源并不只有一条路径。不同工具在采集位置、采样方式、数据粒度和对生产实例的影响上差异很大。选型时如果只比较“能不能看到指标”,很容易在高峰期引入额外负载,或者拿到一堆无法关联的碎片数据。理解每种采集机制的本质,才能设计出既完整又低干扰的生产采集架构。

五类采集方式的机制差异

mongostat 是一个轮询式命令行工具,默认每秒向 mongod 或 mongos 发送一次 serverStatus 命令,把返回结果换算成每秒增量并打印成一行。它适合快速观察 insert、query、update、delete、getmore、command 等操作速率,以及 faults、flushes、vsize、res 等状态。缺点是采样间隔固定、历史数据不落盘,进程退出后数据即丢失,因此它更适合临时排查,而不是长期监控。

mongotop 关注的是集合级别的读写耗时。它同样按固定间隔调用 serverStatus 中的 top 字段,输出每个命名空间在 read/write 上花费的毫秒数。它回答的是“哪个集合最忙”,而不是“哪个操作最慢”。当某个集合的 write 时间持续偏高时,可以进一步结合索引和写入模式分析,但 mongotop 本身不提供查询级别的细节。

db.serverStatus() 是所有这些工具的数据源头。它返回一个庞大的文档,涵盖 connections、opcounters、wiredTiger、repl、metrics、locks、globalLock、tcmalloc 等大量子树。直接调用它可以获得最细的原始数据,但字段多、结构深,人工解析成本高。生产上通常不直接把它作为采集接口,而是由 exporter 或自研脚本按需提取关键字段。

FTDC(Full Time Diagnostic Data Capture) 是 MongoDB 内置的持续诊断数据采集机制。它默认每 1 秒采样一次,把 serverStatus、collStats、replSetGetStatus 等诊断信息压缩写入 diagnostic.data 目录下的二进制文件,默认保留最近一段时间的数据。FTDC 由 mongod 自身完成,不依赖外部轮询,因此对实例的额外压力很小,是事后复盘和故障定位的重要依据。它的局限在于数据格式不便于直接对接通用可视化平台,通常需要 mongodump 或专用工具导出分析。

Prometheus exporter 走的是拉取模型。以 mongodb_exporter 为例,它暴露一个 HTTP 端点,Prometheus 按 scrape_interval 定期抓取,把 serverStatus、replSetGetStatus、collStats 等转换为带标签的时序指标。它的优势是历史数据可长期存储、支持告警规则和 Grafana 可视化,适合作为生产监控的主干。代价是需要额外部署 exporter 进程,并合理控制采集频率和指标基数。

MongoDB 监控采集机制与生产架构 数据源 → 采集层 → 存储/分析层 → 消费层 数据源 serverStatus 原始文档 replSetGetStatus collStats / top 采集层 mongostat / mongotop(临时) FTDC(内置,1s 采样) mongodb_exporter(拉取) 存储与分析 Prometheus TSDB diagnostic.data 日志 / 归档文件 消费 Grafana 告警 复盘分析 采集方式对比与生产定位 采集方式 采样/触发 数据粒度 生产定位 主要限制 mongostat 1s 轮询 实例级操作速率 临时排查 无历史、无告警 mongotop 1s 轮询 集合级读写耗时 热点集合定位 无查询级细节 FTDC 1s 内置采样 全量诊断快照 事后复盘 格式不通用 Prometheus exporter scrape_interval 时序指标 长期监控主干 需控制指标基数

生产采集架构的设计要点

把上述工具组合成生产架构时,核心原则是“分层采集、按需保留、控制开销”。推荐的主干是 Prometheus + mongodb_exporter:每个 mongod 或 mongos 实例旁部署一个 exporter,Prometheus 以 15~30 秒的 scrape_interval 抓取,Grafana 负责展示,Alertmanager 负责告警。这个频率足以捕捉连接数突增、复制延迟上升、opcounters 异常等趋势,又不会给实例带来明显负担。

FTDC 作为内置机制应当保持开启,它不占用额外进程,却能在故障发生后提供秒级粒度的现场数据。当 Prometheus 告警触发时,运维人员可以导出对应时间段的 diagnostic.data,与 Prometheus 曲线交叉验证。mongostat 和 mongotop 则保留为交互式工具,在需要快速确认某个实例或集合的即时状态时使用,不纳入长期采集链路。

指标基数是一个容易被忽视的风险点。mongodb_exporter 默认会暴露大量按 database、collection 维度展开的指标,如果实例上有数千个集合,抓取结果可能达到数万条时间序列,显著增加 Prometheus 内存和存储压力。生产上应通过 exporter 的过滤参数只保留关键数据库和集合,或者关闭 collStats 类高基数指标,仅保留实例级和复制集级指标。

采集频率与告警灵敏度需要权衡。15 秒抓取配合 for: 2m 的告警规则,可以过滤掉瞬时抖动;如果业务对复制延迟极其敏感,可对 repl_lag 单独设置更短的评估窗口,但不宜把全局 scrape_interval 压到 5 秒以下,否则采集本身会成为负担。

一个可落地的采集配置示例

下面给出一个面向生产的最小化 Prometheus 抓取配置片段,假设三节点复制集,每个节点运行一个 exporter,监听 9216 端口:

scrape_configs:
  - job_name: 'mongodb'
    scrape_interval: 15s
    scrape_timeout: 10s
    static_configs:
      - targets:
          - 'mongo-node1:9216'
          - 'mongo-node2:9216'
          - 'mongo-node3:9216'
        labels:
          env: 'prod'
          cluster: 'order-rs'
    metrics_path: /metrics
    relabel_configs:
      - source_labels: [__address__]
        regex: '([^:]+):.*'
        target_label: instance
        replacement: '$1'

exporter 启动时建议加上 --collector.dbstats 和 --collector.replicasetstatus,按需开启 --collector.collstats 并配合 --collstats-filter 限制集合范围。启动后先用 curl http://mongo-node1:9216/metrics | head -50 确认端点可访问,再在 Prometheus 的 Targets 页面确认三个实例均为 UP,最后在 Grafana 中导入 MongoDB 官方或社区仪表盘,观察 mongodb_ss_connections、mongodb_ss_opcounters、mongodb_mongod_replset_member_replication_lag 等关键指标是否正常上报。

不要在同一台主机上为多个 mongod 实例复用同一个 exporter 端口,也不要把 exporter 暴露在公网。exporter 通常以只读权限连接 MongoDB,但仍应通过防火墙或反向代理限制访问来源,仅允许 Prometheus 服务器抓取。

判断采集架构是否达标,可以看三个信号:Prometheus Targets 全部 UP 且抓取耗时稳定;Grafana 上关键指标曲线连续无断点;告警触发后能通过 FTDC 或日志找到对应时间点的细节。如果抓取耗时随集合数量增长而明显上升,说明指标基数需要收敛;如果告警频繁误报,则应调整评估窗口或阈值,而不是简单提高采集频率。