MySQL高级讲座篇之:如何利用`Prometheus`和`Grafana`构建一个多维度的MySQL性能监控看板?

大家好,各位MySQL的铲屎官们!今天咱们不聊风花雪月,只谈如何让你的MySQL数据库乖乖听话,并且把它的健康状况实时展示出来。我们要聊的是如何利用 PrometheusGrafana 构建一个多维度的MySQL性能监控看板。

准备好了吗?咱们开始吧!

第一部分:监控的必要性以及为何选择Prometheus + Grafana

想象一下,你养了一只猫(或者很多只),你肯定不想等到它奄奄一息了才发现它生病了吧?数据库也是一样,预防胜于治疗。一个好的监控系统能让你:

  • 提前预警: 在问题发生之前就发现苗头,比如磁盘空间告急、连接数暴增等。
  • 快速定位问题: 当出现性能瓶颈时,能迅速找到罪魁祸首,是慢查询、锁冲突还是资源不足。
  • 优化性能: 通过监控数据,了解数据库的瓶颈所在,从而进行有针对性的优化。
  • 容量规划: 了解数据库的增长趋势,为未来的扩容做好准备。

那么,为什么选择 PrometheusGrafana 这一对黄金搭档呢?

  • Prometheus: 这是一个开源的监控和警报工具包。它的特点是:

    • 基于时间序列数据: 非常适合监控数据库的各种指标。
    • 强大的查询语言(PromQL): 灵活地查询和聚合监控数据。
    • 易于集成: 可以通过各种 exporters 收集数据。
    • 轻量级: 部署和维护成本较低。
  • Grafana: 这是一个开源的数据可视化工具。它的特点是:

    • 美观的仪表盘: 可以创建各种图表和仪表盘,直观地展示监控数据。
    • 支持多种数据源: 可以从 Prometheus 等数据源中读取数据。
    • 灵活的配置: 可以自定义图表和仪表盘的各种参数。
    • 易于使用: 即使是新手也能快速上手。

简单来说,Prometheus 负责收集和存储数据,Grafana 负责把数据变成漂亮的图表。

第二部分:搭建监控环境

要开始监控MySQL,我们需要以下几个步骤:

  1. 安装 Prometheus
  2. 安装 MySQL Exporter
  3. 配置 Prometheus 抓取 MySQL Exporter 的数据
  4. 安装 Grafana
  5. 在 Grafana 中配置 Prometheus 数据源
  6. 创建 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

注意替换 usernamepasswordhostport 为你的 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 实例的连接数。

举例:创建一个显示当前连接数的仪表盘

  1. 在 Grafana 中,点击 "Add new panel"。
  2. 选择 "Prometheus" 作为数据源。
  3. 在 "Query" 部分,输入 mysql_global_status_threads_connected
  4. 选择 "Graph" 作为图表类型。
  5. 点击 "Save"。

举例:创建一个显示慢查询速率的仪表盘

  1. 在 Grafana 中,点击 "Add new panel"。
  2. 选择 "Prometheus" 作为数据源。
  3. 在 "Query" 部分,输入 rate(mysql_global_status_slow_queries[5m])
  4. 选择 "Graph" 作为图表类型。
  5. 调整 "Y-axis" 的 "Unit" 为 "queries/sec"。
  6. 点击 "Save"。

举例:创建一个显示数据库大小的仪表盘

  1. 在 Grafana 中,点击 "Add new panel"。
  2. 选择 "Prometheus" 作为数据源。
  3. 在 "Query" 部分,输入 mysql_info_schema_size_bytes{schema="your_database"} 替换 your_database 为你的数据库名。
  4. 选择 "Gauge" 作为图表类型 (或者使用 Graph 并配合 sum(mysql_info_schema_size_bytes) by (schema)显示所有数据库)。
  5. 调整 "Unit" 为 "bytes" 或者 "data (IEC)"。
  6. 点击 "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.ymlalertmanager.yml 挂载到容器中,然后重启 Prometheus 和 Alertmanager。

当告警触发时,你就会收到 Email 通知了。

第五部分:总结与最佳实践

恭喜你,现在你已经掌握了使用 PrometheusGrafana 构建 MySQL 性能监控看板的基本技能。

这里总结一些最佳实践:

  • 选择合适的监控指标: 监控的指标不是越多越好,而是要选择那些能反映数据库关键性能的指标。
  • 自定义仪表盘: 根据你的实际需求,创建个性化的仪表盘,突出显示你最关心的指标。
  • 设置合理的告警阈值: 告警阈值要根据你的业务特点来设置,避免误报和漏报。
  • 定期审查和优化监控配置: 随着业务的变化,监控需求也会发生变化,要定期审查和优化监控配置。
  • 使用 Grafana 的模板变量: 可以使用模板变量来动态选择 MySQL 实例、数据库等,提高仪表盘的灵活性。
  • 利用 Grafana 的告警功能: Grafana 也可以直接配置告警,可以作为 Alertmanager 的补充。

希望今天的讲座对你有所帮助。记住,监控是数据库运维的重要组成部分,一个好的监控系统能让你的 MySQL 数据库更加健康稳定。 各位铲屎官们,加油! 让你的MySQL乖乖听话,创造更加美好的明天!

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注