Skip to content

Prometheus + Grafana集成

Prometheus + Grafana是当前最流行的开源监控解决方案之一,能够帮助DBA实现PostgreSQL数据库的全面监控和可视化。通过PostgreSQL Exporter将数据库指标暴露给Prometheus,再通过Grafana进行可视化展示和告警配置,可以实现高效的数据库监控体系。

PostgreSQL Exporter

PostgreSQL Exporter是连接PostgreSQL和Prometheus的桥梁,负责采集数据库的各种指标并暴露给Prometheus。

安装与部署

二进制安装

bash
# 下载最新版本(根据系统架构选择)
wget https://github.com/prometheus-community/postgres_exporter/releases/download/v0.15.0/postgres_exporter-0.15.0.linux-amd64.tar.gz

# 解压并安装
tar -xzf postgres_exporter-0.15.0.linux-amd64.tar.gz
cd postgres_exporter-0.15.0.linux-amd64
cp postgres_exporter /usr/local/bin/

# 创建用户
useradd -rs /bin/false postgres_exporter

# 创建配置文件目录
mkdir -p /etc/postgres_exporter

Docker部署

bash
docker run -d \
  --name postgres_exporter \
  -p 9187:9187 \
  -e DATA_SOURCE_NAME="postgresql://postgres:password@localhost:5432/postgres?sslmode=disable" \
  prometheuscommunity/postgres-exporter:latest

Kubernetes部署

yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: postgres-exporter
  namespace: monitoring
spec:
  replicas: 1
  selector:
    matchLabels:
      app: postgres-exporter
  template:
    metadata:
      labels:
        app: postgres-exporter
    spec:
      containers:
      - name: postgres-exporter
        image: prometheuscommunity/postgres-exporter:latest
        ports:
        - containerPort: 9187
        env:
        - name: DATA_SOURCE_NAME
          value: "postgresql://postgres:password@postgres:5432/postgres?sslmode=disable"
        resources:
          requests:
            memory: "128Mi"
            cpu: "100m"
          limits:
            memory: "256Mi"
            cpu: "500m"
---
apiVersion: v1
kind: Service
metadata:
  name: postgres-exporter
  namespace: monitoring
  annotations:
    prometheus.io/scrape: "true"
    prometheus.io/port: "9187"
spec:
  selector:
    app: postgres-exporter
  ports:
  - port: 9187
    targetPort: 9187

配置数据源

创建一个包含数据库连接信息的配置文件:

bash
# 创建环境变量文件
cat > /etc/postgres_exporter/env << EOF
DATA_SOURCE_NAME=postgresql://postgres_exporter:password@localhost:5432/postgres?sslmode=disable
EOF

# 设置权限
chown postgres_exporter:postgres_exporter /etc/postgres_exporter/env
chmod 600 /etc/postgres_exporter/env

配置systemd服务

bash
# 创建systemd服务文件
cat > /etc/systemd/system/postgres_exporter.service << EOF
[Unit]
Description=PostgreSQL Exporter for Prometheus
After=network.target

[Service]
Type=simple
User=postgres_exporter
Group=postgres_exporter
EnvironmentFile=/etc/postgres_exporter/env
ExecStart=/usr/local/bin/postgres_exporter \
  --web.listen-address=:9187 \
  --web.telemetry-path=/metrics \
  --extend.query-path=/etc/postgres_exporter/queries.yaml
Restart=on-failure

[Install]
WantedBy=multi-user.target
EOF

# 启动服务
systemctl daemon-reload
systemctl enable postgres_exporter
systemctl start postgres_exporter

# 验证服务状态
systemctl status postgres_exporter

自定义查询配置

PostgreSQL Exporter支持自定义SQL查询来采集额外的指标。创建自定义查询文件:

yaml
# /etc/postgres_exporter/queries.yaml
global:
  scrape_interval: 15s

custom_queries:
  - name: pg_database_size
    description: Size of each database in bytes
    query: |
      SELECT datname AS database, pg_database_size(datname) AS size_bytes
      FROM pg_database
      WHERE datistemplate = false
    metrics:
      - database: 
          usage: "LABEL"
          description: "Name of the database"
      - size_bytes: 
          usage: "GAUGE"
          description: "Size of the database in bytes"

  - name: pg_table_size
    description: Size of tables in bytes
    query: |
      SELECT schemaname, tablename, pg_total_relation_size(schemaname || '.' || tablename) AS size_bytes
      FROM pg_tables
      WHERE schemaname NOT IN ('pg_catalog', 'information_schema')
    metrics:
      - schemaname: 
          usage: "LABEL"
          description: "Schema name"
      - tablename: 
          usage: "LABEL"
          description: "Table name"
      - size_bytes: 
          usage: "GAUGE"
          description: "Total size of the table in bytes"

Prometheus配置

配置Prometheus采集规则

编辑Prometheus配置文件,添加PostgreSQL Exporter的采集配置:

yaml
# /etc/prometheus/prometheus.yml
global:
  scrape_interval: 15s
  evaluation_interval: 15s

rule_files:
  # - "first_rules.yml"
  # - "second_rules.yml"

scrape_configs:
  # 监控Prometheus自身
  - job_name: 'prometheus'
    static_configs:
      - targets: ['localhost:9090']

  # 监控PostgreSQL
  - job_name: 'postgresql'
    static_configs:
      - targets: ['localhost:9187']
    scrape_interval: 10s
    scrape_timeout: 5s
    metrics_path: /metrics
    params:
      format: ['prometheus']
    relabel_configs:
      - source_labels: [__address__]
        target_label: instance
        regex: '(.*):9187'
        replacement: 'postgres-$1'

配置服务发现(可选)

对于大规模部署,可以使用服务发现机制自动发现PostgreSQL实例:

文件服务发现

yaml
# prometheus.yml
srape_configs:
  - job_name: 'postgresql'
    file_sd_configs:
      - files: ['/etc/prometheus/targets/postgresql_targets.yml']
        refresh_interval: 5m
yaml
# /etc/prometheus/targets/postgresql_targets.yml
- targets: ['pg1.example.com:9187']
  labels:
    env: 'production'
    cluster: 'main'
- targets: ['pg2.example.com:9187']
  labels:
    env: 'production'
    cluster: 'main'

Consul服务发现

yaml
# prometheus.yml
srape_configs:
  - job_name: 'postgresql'
    consul_sd_configs:
      - server: 'consul:8500'
        services: ['postgresql-exporter']
    relabel_configs:
      - source_labels: [__meta_consul_service_metadata_env]
        target_label: env
      - source_labels: [__meta_consul_service_metadata_cluster]
        target_label: cluster

重启Prometheus

bash
systemctl restart prometheus

Grafana配置

添加Prometheus数据源

  1. 登录Grafana控制台
  2. 点击左侧菜单的"Configuration" -> "Data sources"
  3. 点击"Add data source"
  4. 选择"Prometheus"
  5. 配置Prometheus服务器地址,如http://localhost:9090
  6. 点击"Save & Test"验证连接

导入PostgreSQL仪表盘

Grafana社区提供了丰富的PostgreSQL仪表盘模板,可以直接导入使用:

  1. 点击左侧菜单的"Create" -> "Import"
  2. 输入仪表盘ID,如"9628"(PostgreSQL Overview)或"12683"(PostgreSQL Detailed)
  3. 选择已配置的Prometheus数据源
  4. 点击"Import"完成导入

自定义仪表盘设计

根据实际需求,可以设计自定义的Grafana仪表盘,包含以下关键指标:

1. 数据库连接状态

  • 活跃连接数
  • 等待连接数
  • 连接使用率
  • 连接来源分布

2. 性能指标

  • TPS(每秒事务数)
  • QPS(每秒查询数)
  • 平均查询执行时间
  • 慢查询数量

3. 资源使用情况

  • CPU使用率
  • 内存使用率
  • 磁盘I/O
  • 表空间大小
  • WAL生成速率

4. 复制状态(主从架构)

  • 复制延迟
  • 复制槽状态
  • 同步状态
  • 备库连接状态

5. 缓存命中率

  • 共享缓冲区命中率
  • 索引命中率
  • 计划缓存命中率

6. Vacuum状态

  • Autovacuum运行次数
  • 死元组数
  • 表膨胀率
  • VACUUM执行时间

告警配置

在Grafana中配置告警规则,当指标超过阈值时触发告警:

  1. 进入仪表盘编辑模式
  2. 点击面板标题 -> "Edit"
  3. 切换到"Alert"标签页
  4. 配置告警规则,如:
    • 活跃连接数 > 80%
    • 复制延迟 > 30秒
    • 缓存命中率 < 95%
    • 慢查询数 > 10个/分钟
  5. 配置告警通知渠道(如Email、Slack、Webhook等)

最佳实践

1. 合理设置采集间隔

  • 核心指标(如连接数、TPS):5-10秒
  • 资源指标(如磁盘空间):30秒-1分钟
  • 慢变化指标(如表空间大小):5-10分钟

2. 指标过滤与标签设计

  • 使用标签区分不同环境(production/staging/test)
  • 使用标签区分不同集群和实例
  • 过滤掉不必要的指标,减少存储和查询压力
  • 为关键指标添加业务相关标签

3. 存储策略配置

yaml
# prometheus.yml
storage:
  tsdb:
    path: /var/lib/prometheus
    retention.time: 15d  # 保留15天数据
    retention.size: 10GB  # 最大存储10GB

4. 高可用部署

  • Prometheus采用主备模式部署
  • 使用Thanos或VictoriaMetrics实现长期存储
  • Grafana配置多个数据源,实现高可用
  • 定期备份Grafana仪表盘配置

5. 安全配置

  • 配置Prometheus和Grafana的访问控制
  • 使用HTTPS加密传输
  • 限制PostgreSQL Exporter的访问IP
  • 为PostgreSQL Exporter创建只读用户

6. 监控Exporter本身

  • 监控PostgreSQL Exporter的运行状态
  • 监控Exporter的响应时间
  • 监控Exporter的错误日志
  • 定期验证指标采集的完整性

常见问题与解决方案

1. Exporter无法连接到PostgreSQL

问题:Exporter日志中出现连接错误

解决方案

  • 检查数据库连接字符串是否正确
  • 验证数据库用户权限
  • 检查防火墙设置
  • 验证数据库监听地址配置

2. 部分指标缺失

问题:Grafana仪表盘中某些指标显示为空白

解决方案

  • 检查PostgreSQL Exporter版本是否支持该指标
  • 验证自定义查询是否正确
  • 检查Prometheus采集配置
  • 查看Exporter日志中的错误信息

3. 性能影响

问题:Exporter采集导致数据库性能下降

解决方案

  • 增加采集间隔
  • 减少自定义查询的复杂度
  • 限制采集的指标数量
  • 为Exporter创建专用的监控用户

4. 告警频繁触发

问题:告警规则过于敏感,导致频繁触发

解决方案

  • 调整告警阈值
  • 增加告警持续时间(如连续3分钟超过阈值才触发)
  • 优化告警规则,避免误报
  • 分类告警级别,区分紧急和警告

版本差异注意事项

PostgreSQL Exporter版本差异

版本主要变化
v0.15.0支持PostgreSQL 16,优化了查询性能
v0.14.0新增了wal_receiver指标,改进了复制监控
v0.13.0支持自定义查询的动态标签,增加了pg_stat_statements指标
v0.12.0重构了代码结构,优化了内存使用

Prometheus版本差异

版本主要变化
v2.40+支持native histograms,改进了直方图指标
v2.37+增加了对OpenTelemetry的支持
v2.30+改进了存储引擎,提高了查询性能
v2.20+增加了remote write的压缩功能

部署架构建议

小型部署(1-5个PostgreSQL实例)

┌─────────────────┐      ┌─────────────────┐      ┌─────────────────┐
│  PostgreSQL 1   │──────▶  PostgreSQL 2   │──────▶  PostgreSQL 3   │
└─────────────────┘      └─────────────────┘      └─────────────────┘
        │                        │                        │
        ▼                        ▼                        ▼
┌─────────────────┐      ┌─────────────────┐      ┌─────────────────┐
│PostgreSQL Exporter1│    │PostgreSQL Exporter2│    │PostgreSQL Exporter3│
└─────────────────┘      └─────────────────┘      └─────────────────┘
        │                        │                        │
        └────────────────────────┼────────────────────────┘

                         ┌─────────────────┐
                         │   Prometheus    │
                         └─────────────────┘


                         ┌─────────────────┐
                         │    Grafana      │
                         └─────────────────┘


                         ┌─────────────────┐
                         │   Alertmanager  │
                         └─────────────────┘

大型部署(10+个PostgreSQL实例)

┌─────────────────┐      ┌─────────────────┐      ┌─────────────────┐
│  PostgreSQL 1   │──────▶  PostgreSQL 2   │──────▶  PostgreSQL N   │
└─────────────────┘      └─────────────────┘      └─────────────────┘
        │                        │                        │
        ▼                        ▼                        ▼
┌─────────────────┐      ┌─────────────────┐      ┌─────────────────┐
│PostgreSQL Exporter1│    │PostgreSQL Exporter2│    │PostgreSQL ExporterN│
└─────────────────┘      └─────────────────┘      └─────────────────┘
        │                        │                        │
        └────────────────────────┼────────────────────────┘

                         ┌─────────────────┐
                         │  Consul Server  │
                         └─────────────────┘


         ┌─────────────────────────────────────────────────┐
         │                   ┌─────────────────┐           │
         │                   │   Prometheus    │           │
         │                   └─────────────────┘           │
         │                          │                       │
         │                          ▼                       │
         │                   ┌─────────────────┐           │
         │                   │   Prometheus    │           │
         │                   └─────────────────┘           │
         └─────────────────────────────────────────────────┘


                         ┌─────────────────┐
                         │    Thanos       │
                         └─────────────────┘


                         ┌─────────────────┐
                         │    Grafana      │
                         └─────────────────┘


                         ┌─────────────────┐
                         │   Alertmanager  │
                         └─────────────────┘

通过合理的Prometheus + Grafana集成方案,DBA可以实现PostgreSQL数据库的全面监控和可视化,及时发现和解决性能问题,确保数据库的稳定运行。