Skip to content

TiDB 自定义监控开发 ​

TiDB 提供了完善的监控体系,基于 Prometheus 和 Grafana。除了内置的监控指标外,用户还可以开发自定义监控,满足特定的业务需求。本文档介绍 TiDB 自定义监控的开发方法,包括 Prometheus 指标开发、Grafana 仪表盘开发和监控插件开发等内容。

监控系统架构 ​

1. 基本架构 ​

TiDB 监控系统的基本架构包括:

  • 指标采集层:TiDB、PD、TiKV 等组件暴露 Prometheus 格式的指标
  • 指标存储层:Prometheus 负责存储指标数据
  • 指标展示层:Grafana 负责展示监控数据
  • 告警系统:Prometheus Alertmanager 负责处理告警

2. 指标类型 ​

Prometheus 支持以下指标类型:

  • Counter:单调递增的计数器,如请求数、错误数等
  • Gauge:可以增减的仪表盘,如 CPU 使用率、内存使用率等
  • Histogram:直方图,用于统计分布情况,如请求延迟分布
  • Summary:摘要,用于统计分位数,如请求延迟的 P50、P95、P99 等

自定义 Prometheus 指标开发 ​

1. 在 TiDB 中添加自定义指标 ​

TiDB 提供了 Prometheus 客户端库,可以方便地添加自定义指标。

1.1 添加指标定义 ​

在 TiDB 代码中添加指标定义:

go
// 导入 Prometheus 客户端库
import (
    "github.com/prometheus/client_golang/prometheus"
    "github.com/prometheus/client_golang/prometheus/promauto"
)

// 定义指标
var (
    // 定义一个 Counter 类型的指标
    customRequestsTotal = promauto.NewCounter(
        prometheus.CounterOpts{
            Name: "tidb_custom_requests_total",
            Help: "The total number of custom requests",
            Labels: prometheus.Labels{
                "type": "custom",
            },
        },
    )

    // 定义一个 Gauge 类型的指标
    customGauge = promauto.NewGauge(
        prometheus.GaugeOpts{
            Name: "tidb_custom_gauge",
            Help: "A custom gauge metric",
        },
    )

    // 定义一个 Histogram 类型的指标
    customHistogram = promauto.NewHistogram(
        prometheus.HistogramOpts{
            Name:    "tidb_custom_request_duration_seconds",
            Help:    "The duration of custom requests in seconds",
            Buckets: prometheus.DefBuckets,
        },
    )
)

1.2 更新指标值 ​

在代码中更新指标值:

go
// 增加 Counter 指标
customRequestsTotal.Inc()

// 增加指定值
customRequestsTotal.Add(5)

// 更新 Gauge 指标
customGauge.Set(0.5)
customGauge.Inc()
customGauge.Dec()

// 记录 Histogram 指标
startTime := time.Now()
// 执行操作
elapsed := time.Since(startTime)
customHistogram.Observe(elapsed.Seconds())

2. 开发独立的监控 exporter ​

对于无法直接修改 TiDB 代码的场景,可以开发独立的监控 exporter,定期采集自定义指标并暴露给 Prometheus。

2.1 使用 Go 开发 exporter ​

使用 Prometheus 客户端库开发 exporter:

go
package main

import (
    "log"
    "net/http"
    "time"

    "github.com/prometheus/client_golang/prometheus"
    "github.com/prometheus/client_golang/prometheus/promauto"
    "github.com/prometheus/client_golang/prometheus/promhttp"
)

// 定义指标
var (
    customMetric = promauto.NewGaugeVec(
        prometheus.GaugeOpts{
            Name: "tidb_custom_metric",
            Help: "A custom metric for TiDB",
        },
        []string{"label1", "label2"},
    )
)

func main() {
    // 定期更新指标
    go func() {
        for {
            // 模拟采集指标
            customMetric.WithLabelValues("value1", "value2").Set(1.0)
            time.Sleep(10 * time.Second)
        }
    }()

    // 暴露指标端点
    http.Handle("/metrics", promhttp.Handler())
    log.Fatal(http.ListenAndServe(":8080", nil))
}

2.2 编译和运行 exporter ​

bash
# 编译 exporter
go build -o tidb-custom-exporter main.go

# 运行 exporter
./tidb-custom-exporter

2.3 配置 Prometheus 采集 ​

在 Prometheus 配置文件中添加采集任务:

yaml
scrape_configs:
  - job_name: 'tidb-custom-exporter'
    static_configs:
      - targets: ['localhost:8080']
    scrape_interval: 15s

Grafana 自定义仪表盘开发 ​

1. 仪表盘结构 ​

Grafana 仪表盘由以下部分组成:

  • 面板(Panel):展示单个指标或指标组合
  • 行(Row):组织相关的面板
  • 变量(Variable):用于动态筛选数据
  • 查询(Query):从数据源获取数据
  • 可视化(Visualization):图表类型,如折线图、柱状图、仪表盘等

2. 创建自定义仪表盘 ​

2.1 登录 Grafana ​

访问 Grafana 界面,使用管理员账号登录。

2.2 创建仪表盘 ​

  1. 点击左侧菜单的 "+" 按钮,选择 "Dashboard"
  2. 点击 "Add new panel"
  3. 配置查询:
    • 选择数据源为 Prometheus
    • 输入 PromQL 查询语句,如 rate(tidb_custom_requests_total[5m])
  4. 配置可视化:
    • 选择图表类型,如 "Time series"
    • 配置图表标题、图例、轴标签等
  5. 点击 "Apply" 保存面板
  6. 点击 "Save dashboard" 保存仪表盘

3. 导入和导出仪表盘 ​

3.1 导出仪表盘 ​

  1. 打开要导出的仪表盘
  2. 点击右上角的 "Share" 按钮
  3. 选择 "Export" 标签页
  4. 选择导出选项,如是否包含注释和链接
  5. 点击 "Save to file" 下载 JSON 文件

3.2 导入仪表盘 ​

  1. 点击左侧菜单的 "+" 按钮,选择 "Import"
  2. 选择要导入的 JSON 文件,或粘贴 JSON 内容
  3. 选择数据源
  4. 点击 "Import" 完成导入

4. 仪表盘最佳实践 ​

  • 组织面板:将相关的面板组织在同一行,便于查看
  • 使用变量:使用变量实现动态筛选,提高仪表盘的灵活性
  • 选择合适的图表类型:根据指标类型选择合适的图表类型
  • 设置合理的时间范围:根据监控需求设置合适的时间范围
  • 添加注释:添加关键事件的注释,便于分析问题
  • 设置告警阈值:在面板上显示告警阈值,便于直观查看

监控插件开发 ​

1. TiDB 监控插件架构 ​

TiDB 支持通过插件扩展监控功能。监控插件可以:

  • 采集自定义指标
  • 实现自定义告警
  • 扩展监控展示

2. 开发监控插件 ​

2.1 插件结构 ​

监控插件的基本结构包括:

tidb-monitor-plugin/
├── plugin.json          # 插件元数据
├── main.go             # 插件入口
├── collector/          # 指标采集器
├── alert/              # 告警规则
└── dashboard/          # Grafana 仪表盘

2.2 插件元数据 ​

plugin.json 包含插件的基本信息:

json
{
  "name": "tidb-custom-plugin",
  "version": "1.0.0",
  "description": "A custom monitoring plugin for TiDB",
  "author": "Your Name",
  "dependencies": [],
  "collectors": [
    {
      "name": "custom-collector",
      "type": "prometheus",
      "interval": 15
    }
  ],
  "dashboards": [
    {
      "name": "Custom Dashboard",
      "file": "dashboard/custom-dashboard.json"
    }
  ],
  "alerts": [
    {
      "name": "Custom Alert",
      "file": "alert/custom-alert.yaml"
    }
  ]
}

2.3 采集器开发 ​

开发自定义采集器:

go
package collector

import (
    "context"
    "time"

    "github.com/prometheus/client_golang/prometheus"
)

// CustomCollector 自定义采集器
type CustomCollector struct {
    metric *prometheus.Desc
}

// NewCustomCollector 创建自定义采集器
func NewCustomCollector() *CustomCollector {
    return &CustomCollector{
        metric: prometheus.NewDesc(
            "tidb_custom_metric",
            "A custom metric for TiDB",
            []string{"label"}, nil,
        ),
    }
}

// Describe 实现 prometheus.Collector 接口
func (c *CustomCollector) Describe(ch chan<- *prometheus.Desc) {
    ch <- c.metric
}

// Collect 实现 prometheus.Collector 接口
func (c *CustomCollector) Collect(ch chan<- prometheus.Metric) {
    // 采集指标数据
    value := 1.0
    ch <- prometheus.MustNewConstMetric(
        c.metric,
        prometheus.GaugeValue,
        value,
        "test",
    )
}

3. 安装和使用插件 ​

3.1 安装插件 ​

bash
# 复制插件到 TiDB 监控插件目录
cp -r tidb-monitor-plugin /path/to/tidb-monitor/plugins/

# 重启 TiDB 监控组件
tiup cluster restart <cluster-name> -R monitoring

3.2 使用插件 ​

  • 查看指标:访问 http://[monitor-ip]:9090/metrics 查看自定义指标
  • 查看仪表盘:在 Grafana 中查看导入的自定义仪表盘
  • 查看告警:在 Prometheus Alertmanager 中查看自定义告警

自定义告警规则开发 ​

1. 告警规则格式 ​

Prometheus 告警规则使用 YAML 格式定义:

yaml
groups:
- name: custom-alerts
  rules:
  - alert: CustomAlert
    expr: rate(tidb_custom_requests_total[5m]) > 100
    for: 5m
    labels:
      severity: warning
    annotations:
      summary: "Custom alert is firing"
      description: "The custom request rate is {{ $value }} per second, which is above the threshold of 100."

2. 配置告警规则 ​

2.1 直接配置 ​

将告警规则文件添加到 Prometheus 配置目录:

bash
# 将告警规则文件复制到 Prometheus 配置目录
cp custom-alert.yaml /path/to/prometheus/rules/

# 重启 Prometheus
systemctl restart prometheus

2.2 使用 TiUP 配置 ​

在 TiUP 集群配置文件中添加告警规则:

yaml
global:
  user: "tidb"
  ssh_port: 22
  deploy_dir: "/tidb-deploy"
  data_dir: "/tidb-data"

monitored:
  node_exporter_port: 9100
  blackbox_exporter_port: 9115
  alertmanager_port: 9093
  grafana_port: 3000
  prometheus_port: 9090
  prometheus_retention_time: "15d"
  # 添加自定义告警规则
  alert_rules_files:
    - /path/to/custom-alert.yaml

监控数据导出和分析 ​

1. 导出监控数据 ​

使用 Prometheus API 导出监控数据:

bash
# 导出 5 分钟内的指标数据
curl -g 'http://localhost:9090/api/v1/query_range?query=tidb_custom_requests_total&start=1609459200&end=1609459500&step=15s'

2. 使用 PromQL 分析数据 ​

PromQL 是 Prometheus 的查询语言,可以用于分析监控数据:

2.1 基本查询 ​

# 查询当前值
tidb_custom_gauge

# 查询 5 分钟内的平均值
avg_over_time(tidb_custom_gauge[5m])

# 查询增长率
rate(tidb_custom_requests_total[5m])

# 查询分位数
histogram_quantile(0.95, rate(tidb_custom_request_duration_seconds_bucket[5m]))

2.2 高级查询 ​

# 按标签分组查询
sum by (instance) (rate(tidb_custom_requests_total[5m]))

# 计算比率
sum(rate(tidb_custom_requests_total{status="error"}[5m])) / sum(rate(tidb_custom_requests_total[5m]))

# 预测趋势
predict_linear(tidb_custom_gauge[1h], 3600)

监控最佳实践 ​

1. 指标命名规范 ​

  • 遵循 Prometheus 命名规范,使用下划线分隔单词
  • 指标名称应包含组件名称,如 tidb_、pd_、tikv_ 等
  • 指标名称应清晰描述指标含义,如 tidb_custom_requests_total
  • 使用合适的标签,便于按维度分析

2. 采集频率 ​

  • 对于频繁变化的指标,如请求数,采集频率可以设置为 5-15 秒
  • 对于变化较慢的指标,如 CPU 使用率,采集频率可以设置为 30-60 秒
  • 避免过于频繁的采集,以免增加系统负担

3. 数据保留 ​

  • 根据监控需求设置合适的数据保留时间
  • 对于长期趋势分析,可以考虑使用 Thanos 或 Cortex 等工具扩展 Prometheus 的存储能力

4. 告警规则 ​

  • 告警规则应覆盖关键指标
  • 设置合理的告警阈值,避免误告警
  • 配置多级告警,区分不同严重程度
  • 配置合适的告警通知渠道

5. 仪表盘设计 ​

  • 仪表盘应清晰易懂,重点突出
  • 避免在一个仪表盘上放置过多面板
  • 使用变量实现动态筛选
  • 定期更新和优化仪表盘

常见问题(FAQ) ​

Q1: 如何在 TiDB 中添加自定义指标? ​

A1: 可以通过以下方式在 TiDB 中添加自定义指标:

  • 在 TiDB 代码中使用 Prometheus 客户端库添加指标
  • 开发独立的监控 exporter,暴露自定义指标
  • 使用 TiDB 插件机制开发监控插件

Q2: 如何开发自定义 Grafana 仪表盘? ​

A2: 可以通过以下步骤开发自定义 Grafana 仪表盘:

  • 登录 Grafana,创建新仪表盘
  • 添加面板,配置 PromQL 查询
  • 选择合适的可视化类型
  • 配置变量、注释等高级功能
  • 保存并导出仪表盘

Q3: 如何配置自定义告警规则? ​

A3: 可以通过以下方式配置自定义告警规则:

  • 直接将告警规则文件添加到 Prometheus 配置目录
  • 在 TiUP 集群配置文件中添加告警规则
  • 使用 Prometheus API 动态添加告警规则

Q4: 如何导出和分析监控数据? ​

A4: 可以使用以下方式导出和分析监控数据:

  • 使用 Prometheus API 导出数据
  • 使用 PromQL 分析数据
  • 使用 Grafana 导出 CSV 数据
  • 使用第三方工具如 Thanos、Cortex 等进行长期存储和分析

Q5: 如何优化监控性能? ​

A5: 可以通过以下方式优化监控性能:

  • 合理设置采集频率
  • 减少不必要的指标
  • 使用标签选择器过滤数据
  • 优化 PromQL 查询
  • 扩展 Prometheus 存储能力

Q6: 如何开发 TiDB 监控插件? ​

A6: 可以通过以下步骤开发 TiDB 监控插件:

  • 创建插件目录结构
  • 编写插件元数据文件
  • 开发自定义采集器
  • 开发 Grafana 仪表盘
  • 开发告警规则
  • 安装和测试插件