1. Recording Rules 概述
1.1 什么是 Recording Rules
Recording Rules 是 Prometheus 中一种预计算规则。它允许用户基于已有的即时向量或范围向量表达式,定义一个新的指标名称,并将计算结果按指定频率持续写入 TSDB(时间序列数据库)。
从本质上讲,Recording Rules 是一种查询结果缓存机制:
- 输入:一条 PromQL 查询表达式(通常涉及聚合、运算、范围函数)。
- 输出:一个带有新 metric name 和固定 labels 的时间序列。
- 触发方式:由 Prometheus Server 按
evaluation_interval(默认 15s)周期性执行。
核心定义:Recording Rules 将复杂或高频使用的 PromQL 查询结果物化为新的时间序列,从而降低查询延迟、减少计算开销。
1.2 为什么需要 Recording Rules
在生产环境中,直接使用原始 PromQL 查询会面临三个主要问题:
| 问题 | 表现 | 后果 |
|---|---|---|
| 查询性能瓶颈 | 复杂聚合(如 avg(rate(...[5m])) by (job))每次执行需扫描大量原始样本 |
Dashboard 加载缓慢,API 超时,甚至触发 OOM |
| 计算重复浪费 | 多个 Dashboard 或 Alert 使用相同的子查询(如 rate(node_cpu_seconds_total[5m])) |
同一数据被反复计算,CPU 和内存资源浪费 |
| 查询复杂度失控 | 业务指标需要多层嵌套、多步聚合,PromQL 表达式长达数十行 | 难以维护、难以调试、新人上手成本高 |
Recording Rules 通过预计算 + 物化的方式解决上述问题:
- 性能提升:查询预计算结果只需读取一个时间序列,而非扫描全量原始数据。
- 计算复用:一次计算,多处消费(Dashboard、Alert、Ad-hoc 查询)。
- 查询简化:将复杂表达式拆解为多层 Recording Rules,每层只做一件事。
- 历史回溯:预计算结果保留在 TSDB 中,支持历史趋势分析。
经验数据:在日均 10 万+ 时间序列的集群中,合理使用 Recording Rules 可将 Dashboard 加载时间从 15-30 秒降至 1-3 秒,同时降低 Prometheus CPU 使用率 40%-60%。
1.3 Recording Rules vs Alerting Rules
两者是 Prometheus 规则体系的两大支柱,但目标、输出、使用场景完全不同:
| 对比维度 | Recording Rules | Alerting Rules |
|---|---|---|
| 核心目标 | 预计算并缓存查询结果 | 评估告警条件并触发通知 |
| 输出产物 | 新的时间序列(写入 TSDB) | Alert 实例(发送至 Alertmanager) |
| 执行频率 | 按 evaluation_interval 周期性执行 |
按 evaluation_interval 周期性评估 |
| 表达式要求 | 必须返回一个即时向量 | 必须返回一个即时向量(非零值触发告警) |
| 结果保留 | 持久化到 TSDB,受 retention 控制 | 仅保留告警状态(Pending / Firing / Resolved) |
| 典型用途 | 聚合指标、SLO 计算、Dashboard 加速 | 异常检测、阈值告警、故障通知 |
| 配置位置 | rule_files 中 groups.rules 的 record 字段 |
rule_files 中 groups.rules 的 alert 字段 |
两者可以协同工作:Recording Rules 为 Alerting Rules 提供预计算后的稳定输入,避免告警表达式直接扫描原始数据导致评估延迟或抖动。
常见误区:不要用 Alerting Rules 替代 Recording Rules 来做数据聚合。Alerting Rules 的评估结果不写入 TSDB,无法被 Dashboard 复用;且 Alertmanager 对告警实例有去重和分组逻辑,不适合承载数据缓存职责。
1.4 Recording Rules 工作流程
下图展示了 Recording Rules 在 Prometheus 体系中的完整数据流:
1.5 一个完整的 Recording Rule 示例
以下是一个生产级的 Recording Rule 配置,展示其完整结构:
# /etc/prometheus/rules/recording_rules.yml
groups:
- name: cpu_recording_rules
interval: 15s
rules:
- record: job:cpu_usage_rate5m:avg
expr: |
avg(
rate(node_cpu_seconds_total{mode!="idle"}[5m])
) by (job)
labels:
team: "platform"
tier: "aggregation"
- record: instance:cpu_usage_rate5m:avg
expr: |
avg(
rate(node_cpu_seconds_total{mode!="idle"}[5m])
) by (instance)
labels:
team: "platform"
tier: "detail"
关键字段说明:
| 字段 | 含义 | 必填 |
|---|---|---|
record |
新时间序列的名称,遵循 level:metric:operation 命名规范 |
是 |
expr |
PromQL 表达式,必须返回即时向量 | 是 |
labels |
附加的标签键值对,会合并到结果时间序列中 | 否 |
interval |
组级别评估间隔,覆盖全局 evaluation_interval |
否 |
命名规范建议:推荐使用
level:metric:operation 格式(如 job:cpu_usage_rate5m:avg),便于在 Prometheus UI 和 Grafana 中快速识别指标的来源层级和计算方式。