Prometheus + Grafana 监控系统搭建使用指南-mysqld_exporter 安装与配置
'# Prometheus + Grafana 监控系统搭建使用指南 - mysqld_exporter 安装与配置
一、背景与问题
在现代分布式系统中,MySQL 数据库的监控是保障系统稳定运行的核心环节。传统监控手段往往依赖数据库自带的系统表(如 information_schema)或第三方工具,但存在以下问题:
- 数据延迟:传统查询方式无法实时获取指标
- 性能损耗:频繁查询会增加数据库负载
- 可维护性差:指标格式不统一,难以整合到统一监控体系
- 可视化不足:缺乏直观的指标展示和告警机制
Prometheus + Grafana 监控体系通过以下特性解决了这些问题:
- 实时性:Prometheus 的主动拉取机制确保指标即时获取
- 轻量级:exporter 模块化设计减少系统负担
- 可扩展性:支持自定义指标和多数据源集成
- 可视化:Grafana 提供丰富的图表类型和告警规则配置
二、基本原理
1. 系统架构
+-------------------+ +-------------------+
| MySQL 数据库 | | mysqld_exporter |
+-------------------+ +-------------------+
| |
| 通过 MySQL 协议 | 通过 HTTP 协议
v v
+-------------------+ +-------------------+
| Prometheus |<----| HTTP API |
+-------------------+ +-------------------+
| |
| 通过 HTTP 协议 | 通过 Prometheus
v v
+-------------------+
| Grafana |
+-------------------+2. 数据流原理
- 数据采集:mysqld_exporter 通过 MySQL 的 Performance Schema 和内置的
SHOW STATUS等命令获取指标 - 指标转换:将原始数据转换为 Prometheus 兼容的
Metric格式 - 数据存储:Prometheus 通过 HTTP 轮询获取指标,存储到时序数据库
- 可视化展示:Grafana 通过 Prometheus 数据源读取指标,生成可视化图表
3. 关键技术点
- MySQL 性能模式:通过
SET GLOBAL performance_schema = ON开启性能监控 - 指标暴露:通过 HTTP 接口(如
http://localhost:9104/metrics)暴露指标 - 指标格式:采用 Prometheus 的 exposition format(文本格式,包含
name,type,help等元数据)
三、环境准备
1. 系统要求
| 组件 | 系统要求 |
|---|---|
| MySQL | 5.6+(推荐 8.0+) |
| mysqld_exporter | 0.12.1(最新稳定版) |
| Prometheus | 2.42.0(支持 metric relabel) |
| Grafana | 9.3.5(支持 Prometheus 数据源) |
2. 安装依赖
# Ubuntu/Debian
sudo apt update
sudo apt install -y mysql-server prometheus grafana
# CentOS/RHEL
sudo yum install -y mariadb-server prometheus grafana3. MySQL 配置优化
-- 启用性能模式
SET GLOBAL performance_schema = ON;
-- 创建监控用户
CREATE USER 'exporter'@'localhost' IDENTIFIED BY 'SecurePass123!';
GRANT SELECT ON *.* TO 'exporter'@'localhost';
FLUSH PRIVILEGES;四、核心实现
1. mysqld_exporter 安装
# 下载并解压
wget https://github.com/prometheus/mysqld-exporter/releases/download/0.12.1/mysqld_exporter-0.12.1.linux-amd64.tar.gz
tar -xzf mysqld_exporter-0.12.1.linux-amd64.tar.gz
# 移动到系统路径
sudo mv mysqld_exporter-0.12.1.linux-amd64/mysqld_exporter /usr/local/bin/2. 配置文件示例
# my.cnf 配置文件(需放置在 /etc/my.cnf.d/ 目录)
[mysqld_exporter]
data-source-name = "user=exporter password=SecurePass123! host=127.0.0.1:3306"3. 启动服务
# 基础启动(不带配置文件)
/usr/local/bin/mysqld_exporter --web.listen-address=":9104" --config.my-cnf=/etc/my.cnf.d/mysqld_exporter.cnf
# 带配置文件启动(推荐)
/usr/local/bin/mysqld_exporter --web.listen-address=":9104" --config.my-cnf=/etc/my.cnf.d/mysqld_exporter.cnf --log.level=info4. 配置项说明
| 配置项 | 说明 |
|---|---|
--web.listen-address | HTTP 服务监听地址 |
--log.level | 日志级别(debug/info/warning/error) |
--collectors.enabled | 启用的指标收集器(如 mysql_global_status, mysql_global_variables) |
五、完整案例
1. Prometheus 配置
# prometheus.yml
scrape_configs:
- job_name: 'mysql'
static_configs:
- targets: ['localhost:9104']
metrics_relabel_configs:
- source_labels: [__name__]
regex: 'mysql_(global_status|global_variables|slave_status|slave_io_status|slave_sql_status|innodb_status)'
target_label: __name__2. Grafana 配置
- 添加数据源(Prometheus)
- 创建新仪表盘
- 添加面板(如 MySQL 查询延迟监控)
-- 示例查询
SELECT
100 * SUM( (SELECT COUNT(*) FROM information_schema.PROCESSLIST WHERE COMMAND IN ('Query', 'Binlog Dump')) ) / COUNT(*) AS query_ratio
FROM information_schema.PROCESSLIST
WHERE COMMAND IN ('Query', 'Binlog Dump', 'Sleep');3. 验证监控数据
# 检查 mysqld_exporter 指标
curl http://localhost:9104/metrics | grep mysql_global_status
# 检查 Prometheus 数据
curl http://localhost:9090/api/v1/query?query=mysql_global_status_queries_total六、源码解析
1. 核心模块分析
// mysql.go
func (m *MySQL) collect() error {
// 连接数据库
conn, err := mysqlConnect(m.cfg.DataSourceName)
if err != nil {
return err
}
defer conn.Close()
// 获取全局状态
rows, err := conn.Query("SHOW GLOBAL STATUS")
if err != nil {
return err
}
defer rows.Close()
// 解析指标
for rows.Next() {
var key, value string
if err := rows.Scan(&key, &value); err != nil {
continue
}
m.registerMetric("mysql_global_status", key, value)
}
}2. 指标注册机制
func (m *MySQL) registerMetric(name, key, value string) {
// 构造指标名称
metricName := fmt.Sprintf("%s_%s", name, key)
// 注册指标
m.registerer.MustRegister(
prometheus.NewGauge(
prometheus.GaugeOpts{
Name: metricName,
Help: fmt.Sprintf("MySQL %s status", key),
},
prometheus.MustNewConstMetric(
prometheus.NewDesc(
prometheus.BuildFQName("mysql", "status", key),
"MySQL status metric",
nil,
nil,
),
prometheus.GaugeValue,
1,
[]string{"value"},
),
),
)
}七、进阶使用
1. 自定义指标扩展
// 自定义查询
func (m *MySQL) collectCustom() error {
rows, err := m.conn.Query("SELECT * FROM performance_schema.threads")
if err != nil {
return err
}
for rows.Next() {
var thread_id, state string
if err := rows.Scan(&thread_id, &state); err != nil {
continue
}
m.registerMetric("mysql_thread_state", "thread_id", thread_id, "state", state)
}
}2. 多实例监控
# prometheus.yml
scrape_configs:
- job_name: 'mysql'
static_configs:
- targets: ['localhost:9104', '192.168.1.100:9104']
metrics_relabel_configs:
- source_labels: [__meta_mysql_host]
target_label: __address__3. 高可用架构
# 使用 Prometheus 的服务发现
scrape_configs:
- job_name: 'mysql'
kubernetes_sd_configs:
- role: endpoints
relabel_configs:
- source_labels: [__meta_kubernetes_service_name, __meta_kubernetes_endpoint_port_name]
regex: mysql,mysql
- target_label: __address__
replacement: 10.10.10.10:9104八、性能与工程实践
1. 性能优化策略
| 优化措施 | 效果 |
|---|---|
| 调整 scrape_interval | 减少资源消耗 |
| 启用指标过滤 | 降低数据量 |
| 使用内存缓存 | 提升查询速度 |
| 分片监控实例 | 降低单点负载 |
2. 异常处理机制
func (m *MySQL) collect() error {
// 设置超时
conn, err := mysqlConnect(m.cfg.DataSourceName, 5*time.Second)
if err != nil {
log.Error("Failed to connect to MySQL: ", err)
return err
}
// 设置重试机制
for i := 0; i < 3; i++ {
rows, err := conn.Query("SHOW GLOBAL STATUS")
if err == nil {
break
}
time.Sleep(time.Second * 1 << i)
}
}3. 安全加固措施
# 配置 TLS
--web.tls-cert-path=/etc/ssl/cert.pem \
--web.tls-key-path=/etc/ssl/key.pem \
--web.listen-address=":9104"九、常见问题与踩坑
1. 典型错误场景
| 问题描述 | 解决方案 |
|---|---|
| 无法访问 HTTP 接口 | 检查防火墙设置 |
| 指标无法获取 | 检查 MySQL 权限 |
| 指标数据不完整 | 检查配置文件格式 |
| Prometheus 报错 "scrape error" | 检查服务是否运行 |
2. 常见错误示例
# 错误配置(未指定监听地址)
/usr/local/bin/mysqld_exporter --config.my-cnf=/etc/my.cnf.d/mysqld_exporter.cnf
# 正确配置
/usr/local/bin/mysqld_exporter --web.listen-address=":9104" --config.my-cnf=/etc/my.cnf.d/mysqld_exporter.cnf3. 安全风险分析
| 风险点 | 防范措施 |
|---|---|
| 未授权访问 | 配置 HTTP 认证 |
| 指标泄露 | 滤除敏感指标 |
| SQL 注入攻击 | 使用预编译语句 |
十、最佳实践
1. 推荐配置方案
- 使用
--log.level=info保持日志可读性 - 配置
--scrape-interval=10s平衡实时性和资源消耗 - 启用
--collectors.enabled=mysql_global_status等核心指标 - 使用
--web.metrics-path=/metrics避免路径冲突
2. 监控指标推荐
| 指标名称 | 用途 |
|---|---|
mysql_global_status_queries_total | 查询总数 |
mysql_global_status_connections | 当前连接数 |
mysql_global_status_threads_cached | 缓存线程数 |
mysql_slave_status_seconds_behind_master | 主从延迟 |
3. 系统健康检查
# 检查服务状态
systemctl status mysqld_exporter
# 检查日志
tail -n 100 /var/log/mysqld_exporter.log
# 检查 Prometheus 数据
curl http://localhost:9090/api/v1/query?query=mysql_global_status_connections十一、总结
通过本文的深度解析,我们全面了解了如何搭建基于 Prometheus 和 Grafana 的 MySQL 监控系统。核心要点包括:
- 原理理解:深入掌握 mysqld_exporter 的数据采集机制和指标转换原理
- 实践应用:通过完整案例展示了从安装配置到可视化监控的全过程
- 问题排查:分析了常见错误场景和解决方案
- 性能优化:提供了多种性能调优策略
- 安全防护:强调了监控系统安全性的关键点
在实际项目中,建议采用以下策略:
- 生产环境:启用 HTTPS 和基本认证,定期更新版本
- 开发测试:使用内存数据库模拟监控,避免真实数据污染
- 混合架构:对于多实例系统,结合服务发现机制实现动态监控
这种监控方案特别适合需要实时监控数据库性能的场景,如金融系统、大数据处理平台等。但需注意,对于对数据一致性要求极高的关键业务系统,应配合数据库内置的告警机制使用。
评论已关闭