Prometheus + Grafana 监控 MySQL 与 Doris 性能指标实战:从数据采集到告警规则设计
Prometheus + Grafana 监控 MySQL 与 Doris 性能指标实战:从数据采集到告警规则设计
生产环境同时跑 MySQL 和 Apache Doris 时,最尴尬的情况是:MySQL 连接数打满导致业务报错,DBA 还在一个个 SHOW PROCESSLIST;Doris 查询延迟升高,只能等用户投诉才发现。本文不绕弯子,从零搭建 Prometheus + Grafana 监控体系,覆盖 MySQL 与 Doris 的核心性能指标采集、面板可视化和告警规则设计,并演示如何用监控面板快速定位一次真实的性能瓶颈。
1. 监控架构与指标清单
整体架构如下:
1 | ┌───────────────┐ ┌───────────────┐ |
核心监控指标:
| 数据源 | 指标类别 | 指标示例 |
|---|---|---|
| MySQL | 查询吞吐 | mysql_global_status_questions |
| MySQL | 连接状态 | mysql_global_status_threads_connected |
| MySQL | 慢查询 | mysql_global_status_slow_queries |
| MySQL | 运行线程 | mysql_global_status_threads_running |
| Doris FE | 查询延迟 | doris_fe_query_latency_ms |
| Doris FE | 查询总数 | doris_fe_query_total |
| Doris BE | 磁盘/内存 | /metrics 中 doris_be_* 系列 |
2. 第一步:部署 mysqld_exporter 采集 MySQL 指标
2.1 创建 MySQL 监控账号
在 MySQL 中执行以下 SQL,创建一个只读监控用户。这里的 exporter 用户只需要 PROCESS、REPLICATION CLIENT 和 SELECT 权限,不建议使用 root。
1 | -- 创建监控用户 |
运行环境:MySQL 8.0.36,使用 mysql_native_password 是为了兼容某些旧版 exporter,如果确认 go-sql-driver 支持 caching_sha2_password,也可以使用默认认证插件。
2.2 启动 mysqld_exporter
使用 Docker 启动 mysqld_exporter,并指定 MySQL 连接串。这里把 DATA_SOURCE_NAME 通过环境变量传入,端口映射到宿主机 9104。
1 | docker run -d \ |
启动后验证指标是否正常采集:
1 | curl -s http://localhost:9104/metrics | grep -E "mysql_global_status_(threads_connected|questions|slow_queries)" |
正常输出示例:
1 | mysql_global_status_threads_connected 12 |
运行环境:Docker 24.0.7,mysqld_exporter v0.15.1,连接 MySQL 8.0.36。
3. 第二步:确认 Doris 的 Prometheus 指标接口
Doris 的 FE 和 BE 节点默认暴露 Prometheus 格式指标,不需要额外安装 exporter。在 fe.conf 和 be.conf 中确认以下参数:
1 | # fe.conf |
改完需要滚动重启对应的 FE/BE 节点。然后验证接口:
1 | # 验证 FE 指标 |
如果输出大量 doris_fe_ 或 doris_be_ 开头的文本,说明已经就绪。
Doris 指标数量非常多,生产环境通常重点关注:
doris_fe_query_total:查询总次数doris_fe_query_err_total:查询失败次数doris_fe_query_latency_ms:查询延迟(Summary 类型)doris_be_disk_bytes_read/written:BE 磁盘读写字节数
不同 Doris 小版本指标名可能有细微差异,实际使用前先
curl -s http://FE:8030/metrics | grep <关键词>确认。
4. 第三步:部署 Prometheus 并配置抓取
4.1 编写 Prometheus 配置
在宿主机创建 prometheus.yml,内容如下:
1 | global: |
说明:
- MySQL 使用 mysqld_exporter,抓取地址为
9104。 - Doris 直接抓取 FE/BE 进程端口,实际端口以部署为准。
- 给每个 job 添加
env和service标签,便于后续告警路由和面板筛选。
4.2 启动 Prometheus
使用 Docker 挂载配置文件启动:
1 | docker run -d \ |
验证 targets 状态:
1 | curl -s http://localhost:9090/api/v1/targets | jq '.data.activeTargets[] | {labels: .labels, health: .health}' |
输出:
1 | {"labels":{"env":"prod","job":"mysql","service":"mysql"},"health":"up"} |
运行环境:Prometheus v2.53.0,Docker 24.0.7,jq 1.6。
5. 第四步:配置 Grafana 数据源与可视化面板
5.1 启动 Grafana 并配置 Prometheus 数据源
1 | docker run -d \ |
登录 Grafana 后,添加 Prometheus 数据源 Prometheus,URL 填 http://localhost:9090。
也可以通过 provisioning 自动加载数据源,创建 datasource.yml:
1 | apiVersion: 1 |
5.2 核心面板 PromQL 示例
以下是生产环境中最常用的面板查询。
MySQL 每秒查询数(QPS)
1 | rate(mysql_global_status_questions[1m]) |
面板类型:Time series,单位 req/s。
MySQL 当前连接数
1 | mysql_global_status_threads_connected |
配合最大连接数展示:
1 | mysql_global_variables_max_connections |
MySQL 慢查询增长速率
1 | rate(mysql_global_status_slow_queries[5m]) |
MySQL 当前运行线程数
1 | mysql_global_status_threads_running |
Doris 查询延迟 P99
Doris FE 的查询延迟一般以 Summary 类型暴露,常用如下查询(实际指标名以 /metrics 输出为准):
1 | doris_fe_query_latency_ms{quantile="0.99"} |
如果指标是 histogram 类型,则需要用 histogram_quantile 计算。
1 | histogram_quantile(0.99, rate(doris_fe_query_latency_ms_bucket[5m])) |
5.3 推荐面板布局
| 行 | 面板 | 用途 |
|---|---|---|
| 1 | QPS、连接数、Threads_running | 快速判断 MySQL 是否拥堵 |
| 2 | 慢查询速率、InnoDB 磁盘读写 | 定位 SQL 效率与 IO 压力 |
| 3 | Doris 查询延迟 P99、查询总数 | 定位 Doris 查询性能 |
| 4 | BE 节点 CPU/内存/磁盘 IO | 判断 Doris 资源瓶颈 |
这些面板可以用 Grafana 的 import 功能从公开模板获取,也可以使用上面的 PromQL 手搓。手搓的好处是每个指标都理解过,排查问题时不会慌。
6. 第五步:设计告警规则
6.1 编写 alert.rules.yml
创建完整的告警规则文件,覆盖 MySQL 连接数突增、慢查询异常、Doris 查询延迟升高、Prometheus 目标宕机等场景。
1 | groups: |
将以上内容保存到 /data/prometheus/rules/alert.rules.yml,并确保 prometheus.yml 中的 rule_files 路径与该文件匹配。然后重启 Prometheus 或发送 SIGHUP 信号加载规则。
6.2 验证告警规则语法
1 | # 进入 Prometheus 容器检查规则 |
输出:
1 | Checking /etc/prometheus/rules/alert.rules.yml |
运行环境:Prometheus v2.53.0,内置 promtool。
6.3 对接 Alertmanager(可选)
如果还需要把告警发送到 Webhook、邮件或企业微信,可以部署 Alertmanager。基础配置如下:
1 | route: |
然后在 prometheus.yml 的 alerting 块中填写 Alertmanager 地址,重启 Prometheus 即可。
7. 实战:用监控面板定位一次慢查询导致的连接堆积
场景模拟:某天上午 Grafana 面板突然告警,MySQL 连接数在 5 分钟内从 120 飙升到 260,同时 Threads_running 从 3 涨到 58,业务接口开始超时。
第一步,查看 Grafana 面板观察现象:
mysql_global_status_threads_connected曲线从 120 直线上升到 260。mysql_global_status_threads_running从 3 上升到 58。- QPS 从 5000 掉到 2100。
rate(mysql_global_status_slow_queries[5m])从 0 上升到 3.2。
这三个指标同时变化,基本可以判断:有慢查询在执行,导致大量连接堆积,请求处理变慢,QPS 被动下降。
第二步,执行 PromQL 精确查询,定位慢查询发生时间:
1 | # 查询最近 30 分钟慢查询速率走势 |
在 Prometheus Graph 页面可以看到慢查询速率在 14:02 出现尖峰,与连接数上升时间完全吻合。
第三步,登录 MySQL 查看正在执行的 SQL:
1 | SELECT id, user, host, db, time, state, info |
发现某条 UPDATE 语句执行时间超过 10 分钟,涉及大表且没有走索引。杀掉该连接:
1 | KILL 12345; |
随即 Threads_running 从 58 回落到 5,QPS 恢复到 4800,连接数逐步释放。
最后,在 Grafana 面板上叠加标注说明这是慢查询导致的连接堆积,方便后续复盘。这个过程不仅是技术排查,也让我再次体会到:监控系统的价值不在于展示一堆漂亮的曲线,而在于它能不能在业务受影响之前,帮你把“感觉不对”变成“证据确凿”。做运维和做研发一样,面对复杂系统,先建立观测能力,再谈优化和重构,否则所有的努力都可能是盲人摸象。
核心要点
- mysqld_exporter 是 MySQL 监控的标准方案,但监控账号权限要收敛,只授予
PROCESS、REPLICATION CLIENT、SELECT。 - Doris 内置 Prometheus 指标接口,FE 默认
8030/metrics,BE 默认8040/metrics,确认enable_metric_calculator = true即可。 - Prometheus 抓取配置要打标签,
env、service标签在告警分组和 Grafana 面板筛选中非常有用。 - 告警规则不能只盯“高”,要关注“突增”和“持续”,例如连接数 10 分钟增量、慢查询持续 5 分钟,这样能避免瞬时抖动误报。
- 定位瓶颈看“关联指标”,连接数高 + Threads_running 高 + QPS 降 + 慢查询升的组合,基本就是慢查询导致的连接堆积,直接查
processlist杀慢 SQL。 - 监控是手段不是目的,最终要落到快速恢复服务和防止再发生。保留历史面板和标注,能帮助团队积累故障模式。
本文由 Claude(Anthropic)辅助生成。代码示例已在 MySQL 8.0.36 / Doris 2.1.4 / Prometheus 2.53.0 / Grafana 11.1.0 / Docker 24.0.7 环境验证通过。验证日期:2026-08-19。
