大家好,各位MySQL的铲屎官们!今天咱们不聊风花雪月,只谈如何让你的MySQL数据库乖乖听话,并且把它的健康状况实时展示出来。我们要聊的是如何利用 Prometheus
和 Grafana
构建一个多维度的MySQL性能监控看板。
准备好了吗?咱们开始吧!
第一部分:监控的必要性以及为何选择Prometheus
+ Grafana
想象一下,你养了一只猫(或者很多只),你肯定不想等到它奄奄一息了才发现它生病了吧?数据库也是一样,预防胜于治疗。一个好的监控系统能让你:
- 提前预警: 在问题发生之前就发现苗头,比如磁盘空间告急、连接数暴增等。
- 快速定位问题: 当出现性能瓶颈时,能迅速找到罪魁祸首,是慢查询、锁冲突还是资源不足。
- 优化性能: 通过监控数据,了解数据库的瓶颈所在,从而进行有针对性的优化。
- 容量规划: 了解数据库的增长趋势,为未来的扩容做好准备。
那么,为什么选择 Prometheus
和 Grafana
这一对黄金搭档呢?
-
Prometheus: 这是一个开源的监控和警报工具包。它的特点是:
- 基于时间序列数据: 非常适合监控数据库的各种指标。
- 强大的查询语言(PromQL): 灵活地查询和聚合监控数据。
- 易于集成: 可以通过各种 exporters 收集数据。
- 轻量级: 部署和维护成本较低。
-
Grafana: 这是一个开源的数据可视化工具。它的特点是:
- 美观的仪表盘: 可以创建各种图表和仪表盘,直观地展示监控数据。
- 支持多种数据源: 可以从 Prometheus 等数据源中读取数据。
- 灵活的配置: 可以自定义图表和仪表盘的各种参数。
- 易于使用: 即使是新手也能快速上手。
简单来说,Prometheus
负责收集和存储数据,Grafana
负责把数据变成漂亮的图表。
第二部分:搭建监控环境
要开始监控MySQL,我们需要以下几个步骤:
- 安装 Prometheus
- 安装 MySQL Exporter
- 配置 Prometheus 抓取 MySQL Exporter 的数据
- 安装 Grafana
- 在 Grafana 中配置 Prometheus 数据源
- 创建 Grafana 仪表盘
咱们一步一步来。这里以 Docker 方式安装为例,方便快捷。
1. 安装 Prometheus
首先,创建一个 prometheus.yml
配置文件:
global:
scrape_interval: 15s # 抓取数据的间隔
evaluation_interval: 15s # 规则评估的间隔
scrape_configs:
- job_name: 'prometheus'
static_configs:
- targets: ['localhost:9090'] # Prometheus 自身
# 这里先留空,稍后配置 MySQL Exporter
然后,使用 Docker 运行 Prometheus:
docker run -d
-p 9090:9090
-v $(pwd)/prometheus.yml:/etc/prometheus/prometheus.yml
prom/prometheus:latest
打开浏览器,访问 http://localhost:9090
,如果能看到 Prometheus 的界面,就说明安装成功了。
2. 安装 MySQL Exporter
MySQL Exporter 负责从 MySQL 数据库中收集各种指标。这里使用 prom/mysqld-exporter
:
docker run -d
--name mysqld-exporter
-p 9104:9104
-e DATA_SOURCE_NAME="username:password@(host:port)/"
prom/mysqld-exporter:latest
注意替换 username
、password
、host
和 port
为你的 MySQL 数据库的实际信息。
重要提示: DATA_SOURCE_NAME 的格式是固定的,不要写错。 另外,这个用户需要有足够的权限才能读取 MySQL 的监控数据,建议创建一个专门的监控用户,并授予 PROCESS
, REPLICATION CLIENT
, SELECT ON performance_schema.*
权限。
例如:
CREATE USER 'exporter'@'%' IDENTIFIED BY 'your_password';
GRANT PROCESS, REPLICATION CLIENT, SELECT ON performance_schema.* TO 'exporter'@'%';
FLUSH PRIVILEGES;
3. 配置 Prometheus 抓取 MySQL Exporter 的数据
修改 prometheus.yml
配置文件,添加 MySQL Exporter 的配置:
global:
scrape_interval: 15s
evaluation_interval: 15s
scrape_configs:
- job_name: 'prometheus'
static_configs:
- targets: ['localhost:9090']
- job_name: 'mysql'
static_configs:
- targets: ['localhost:9104'] # MySQL Exporter
保存文件后,重启 Prometheus:
docker restart <prometheus_container_id>
在 Prometheus 的界面中,点击 "Status" -> "Targets",如果能看到 MySQL Exporter 的状态是 "UP",就说明配置成功了。
4. 安装 Grafana
docker run -d
--name grafana
-p 3000:3000
-v grafana_data:/var/lib/grafana
grafana/grafana:latest
打开浏览器,访问 http://localhost:3000
,默认用户名和密码是 admin/admin
。
5. 在 Grafana 中配置 Prometheus 数据源
- 登录 Grafana。
- 点击左侧导航栏的 "Configuration" (齿轮图标) -> "Data sources"。
- 点击 "Add data source"。
- 选择 "Prometheus"。
- 在 "HTTP" 部分,设置 "URL" 为
http://localhost:9090
。 - 点击 "Save & test",如果显示 "Data source is working",就说明配置成功了。
6. 创建 Grafana 仪表盘
终于到了最激动人心的时刻了!我们可以开始创建漂亮的仪表盘了。
- 点击左侧导航栏的 "+" -> "Dashboard"。
- 点击 "Add new panel"。
- 在 "Query" 部分,选择 "Prometheus" 作为数据源。
- 在 "Metric browser" 中,输入 PromQL 查询语句。
- 选择合适的图表类型。
- 点击 "Save"。
第三部分:常用的监控指标和 PromQL 查询语句
现在,咱们来聊聊一些常用的 MySQL 监控指标以及如何使用 PromQL 查询它们。
指标名称 | 描述 | PromQL 查询语句 |
---|---|---|
mysql_up |
MySQL 实例是否运行 | mysql_up |
mysql_global_status_uptime |
MySQL 运行时间(秒) | mysql_global_status_uptime |
mysql_global_status_threads_connected |
当前连接的线程数 | mysql_global_status_threads_connected |
mysql_global_status_threads_created |
创建的线程总数 | mysql_global_status_threads_created |
mysql_global_status_threads_cached |
缓存的线程数 | mysql_global_status_threads_cached |
mysql_global_status_questions |
执行的查询总数 | mysql_global_status_questions |
mysql_global_status_slow_queries |
慢查询的数量 | mysql_global_status_slow_queries |
mysql_global_status_bytes_received |
接收的字节数 | mysql_global_status_bytes_received |
mysql_global_status_bytes_sent |
发送的字节数 | mysql_global_status_bytes_sent |
mysql_global_status_innodb_row_lock_time |
InnoDB 行锁等待的总时间(毫秒) | mysql_global_status_innodb_row_lock_time |
mysql_global_status_innodb_row_lock_waits |
InnoDB 行锁等待的次数 | mysql_global_status_innodb_row_lock_waits |
mysql_global_status_innodb_buffer_pool_reads |
InnoDB 缓冲池从磁盘读取的次数 | mysql_global_status_innodb_buffer_pool_reads |
mysql_global_status_innodb_buffer_pool_read_requests |
InnoDB 缓冲池读取请求的总次数 | mysql_global_status_innodb_buffer_pool_read_requests |
mysql_global_status_innodb_buffer_pool_pages_dirty |
InnoDB 缓冲池中的脏页数量 | mysql_global_status_innodb_buffer_pool_pages_dirty |
mysql_global_status_innodb_buffer_pool_pages_free |
InnoDB 缓冲池中的空闲页数量 | mysql_global_status_innodb_buffer_pool_pages_free |
mysql_global_status_innodb_buffer_pool_pages_total |
InnoDB 缓冲池中的总页数 | mysql_global_status_innodb_buffer_pool_pages_total |
mysql_info_schema_size_bytes |
数据库大小 (需要指定数据库名, 如 database="your_database" ) |
mysql_info_schema_size_bytes{schema="your_database"} |
PromQL 进阶用法:
- 计算速率: 使用
rate()
函数计算一段时间内的速率,例如:rate(mysql_global_status_questions[5m])
表示过去 5 分钟内每秒执行的查询数。 - 计算平均值: 使用
avg_over_time()
函数计算一段时间内的平均值,例如:avg_over_time(mysql_global_status_threads_connected[1h])
表示过去 1 小时内的平均连接数。 - 聚合数据: 使用
sum()
、avg()
、max()
、min()
等函数聚合数据,例如:sum(mysql_info_schema_size_bytes) by (schema)
表示按数据库计算总大小。 - 过滤数据: 使用
{}
过滤数据,例如:mysql_global_status_threads_connected{instance="your_mysql_instance"}
表示只显示特定 MySQL 实例的连接数。
举例:创建一个显示当前连接数的仪表盘
- 在 Grafana 中,点击 "Add new panel"。
- 选择 "Prometheus" 作为数据源。
- 在 "Query" 部分,输入
mysql_global_status_threads_connected
。 - 选择 "Graph" 作为图表类型。
- 点击 "Save"。
举例:创建一个显示慢查询速率的仪表盘
- 在 Grafana 中,点击 "Add new panel"。
- 选择 "Prometheus" 作为数据源。
- 在 "Query" 部分,输入
rate(mysql_global_status_slow_queries[5m])
。 - 选择 "Graph" 作为图表类型。
- 调整 "Y-axis" 的 "Unit" 为 "queries/sec"。
- 点击 "Save"。
举例:创建一个显示数据库大小的仪表盘
- 在 Grafana 中,点击 "Add new panel"。
- 选择 "Prometheus" 作为数据源。
- 在 "Query" 部分,输入
mysql_info_schema_size_bytes{schema="your_database"}
替换your_database
为你的数据库名。 - 选择 "Gauge" 作为图表类型 (或者使用 Graph 并配合
sum(mysql_info_schema_size_bytes) by (schema)
显示所有数据库)。 - 调整 "Unit" 为 "bytes" 或者 "data (IEC)"。
- 点击 "Save"。
第四部分:告警配置
光有监控还不够,我们需要配置告警,以便在出现问题时及时通知我们。
Prometheus 有自己的告警规则,可以通过配置文件 prometheus.yml
来定义。但是,更常见的方式是使用 Alertmanager 来管理告警。
1. 安装 Alertmanager
docker run -d
--name alertmanager
-p 9093:9093
-v alertmanager_data:/data
prom/alertmanager:latest
2. 配置 Prometheus 使用 Alertmanager
修改 prometheus.yml
配置文件,添加 Alertmanager 的配置:
global:
scrape_interval: 15s
evaluation_interval: 15s
scrape_configs:
- job_name: 'prometheus'
static_configs:
- targets: ['localhost:9090']
- job_name: 'mysql'
static_configs:
- targets: ['localhost:9104']
rule_files:
- "rules.yml" # 告警规则文件
3. 创建告警规则文件 rules.yml
groups:
- name: MySQLAlerts
rules:
- alert: MySQLDown
expr: mysql_up == 0
for: 1m
labels:
severity: critical
annotations:
summary: "MySQL instance is down"
description: "MySQL instance {{ $labels.instance }} has been down for more than 1 minute."
- alert: HighThreadCount
expr: mysql_global_status_threads_connected > 100
for: 5m
labels:
severity: warning
annotations:
summary: "High thread count"
description: "MySQL instance {{ $labels.instance }} has a high thread count ({{ $value }} > 100) for more than 5 minutes."
- alert: HighSlowQueries
expr: rate(mysql_global_status_slow_queries[5m]) > 1
for: 5m
labels:
severity: warning
annotations:
summary: "High slow query rate"
description: "MySQL instance {{ $labels.instance }} has a high slow query rate ({{ $value }} > 1 query/sec) for more than 5 minutes."
这个文件定义了三个告警规则:
MySQLDown
: 当 MySQL 实例停止运行超过 1 分钟时触发告警。HighThreadCount
: 当连接数超过 100 持续 5 分钟时触发告警。HighSlowQueries
: 当慢查询速率超过 1 次/秒 持续 5 分钟时触发告警。
4. 配置 Alertmanager
Alertmanager 的配置文件 alertmanager.yml
定义了如何处理告警。这里以一个简单的配置为例,将告警发送到 Email:
global:
smtp_smarthost: 'smtp.example.com:587' # SMTP 服务器地址
smtp_auth_username: '[email protected]' # SMTP 用户名
smtp_auth_password: 'your_password' # SMTP 密码
smtp_from: '[email protected]' # 发件人邮箱
smtp_require_tls: true # 是否需要 TLS 加密
route:
receiver: 'email-receiver' # 接收器名称
receivers:
- name: 'email-receiver'
email_configs:
- to: '[email protected]' # 收件人邮箱
重要提示: 替换 smtp.example.com
、[email protected]
和 your_password
为你的实际信息。
将 rules.yml
和 alertmanager.yml
挂载到容器中,然后重启 Prometheus 和 Alertmanager。
当告警触发时,你就会收到 Email 通知了。
第五部分:总结与最佳实践
恭喜你,现在你已经掌握了使用 Prometheus
和 Grafana
构建 MySQL 性能监控看板的基本技能。
这里总结一些最佳实践:
- 选择合适的监控指标: 监控的指标不是越多越好,而是要选择那些能反映数据库关键性能的指标。
- 自定义仪表盘: 根据你的实际需求,创建个性化的仪表盘,突出显示你最关心的指标。
- 设置合理的告警阈值: 告警阈值要根据你的业务特点来设置,避免误报和漏报。
- 定期审查和优化监控配置: 随着业务的变化,监控需求也会发生变化,要定期审查和优化监控配置。
- 使用 Grafana 的模板变量: 可以使用模板变量来动态选择 MySQL 实例、数据库等,提高仪表盘的灵活性。
- 利用 Grafana 的告警功能: Grafana 也可以直接配置告警,可以作为 Alertmanager 的补充。
希望今天的讲座对你有所帮助。记住,监控是数据库运维的重要组成部分,一个好的监控系统能让你的 MySQL 数据库更加健康稳定。 各位铲屎官们,加油! 让你的MySQL乖乖听话,创造更加美好的明天!