4. Recording Rules 生命周期:规则加载、评估、存储、过期

Recording Rules 并非静态配置,而是经历从加载到过期的完整生命周期。理解这一生命周期,有助于诊断规则延迟、数据空洞和存储膨胀等问题。本章将生命周期拆解为四个阶段:加载、评估、存储、过期,并深入每个阶段的内部机制与最佳实践。

4.1 生命周期总览

下图展示了 Recording Rule 从配置文件读取到最终数据过期的完整流转路径:

Recording Rules 生命周期流程图 Recording Rules 生命周期 1. 规则加载 文件解析 / 重载 2. 规则评估 PromQL 执行 / 时间对齐 3. 结果存储 TSDB 写入 / 压缩 4. 数据过期 保留策略 / 块删除 配置重载触发重新加载 评估间隔由 rule_eval_duration 和 group interval 共同控制

4.2 阶段一:规则加载

规则加载是生命周期的起点。Prometheus 在启动时以及运行中通过 SIGHUP 或 HTTP API 触发规则文件重载。

4.2.1 加载流程

  1. 文件读取:Prometheus 读取 rule_files 中配置的所有 YAML 文件。
  2. 语法解析:校验 YAML 结构、PromQL 表达式合法性、标签配置是否正确。
  3. 规则分组:按 groups 组织规则,每个 group 拥有独立的评估间隔。
  4. 状态初始化:为每条规则创建评估状态跟踪器,记录上次评估时间、错误计数等。
关键指标:
prometheus_rule_group_last_duration_seconds — 规则组最近一次评估耗时
prometheus_rule_group_last_evaluation_timestamp_seconds — 规则组最近一次评估时间戳
prometheus_rule_group_rules — 规则组内规则数量

4.2.2 加载失败处理

错误类型 影响范围 恢复方式
YAML 语法错误 整个规则文件无法加载 修正文件后重载
PromQL 解析失败 单条规则被跳过 修正表达式后重载
标签冲突 单条规则被跳过 移除冲突标签后重载
文件不存在 启动失败 / 运行中忽略 恢复文件或更新配置
注意:Prometheus 在启动时如果规则文件加载失败,会直接退出。生产环境中应使用配置管理工具(如 Ansible、Kubernetes ConfigMap)确保规则文件始终有效。

4.3 阶段二:规则评估

评估是 Recording Rules 的核心阶段。Prometheus 按照规则组的 interval 定时执行 PromQL 查询,并将结果写入 TSDB。

4.3.1 评估时间对齐

Prometheus 采用时间对齐策略:评估时间总是对齐到 interval 的整数倍。例如 interval: 30s,评估时间点为 00:00:00、00:00:30、00:01:00…… 而非相对于启动时间。

# 规则组配置示例
groups:
  - name: example_group
    interval: 30s
    rules:
      - record: job:http_requests:rate5m
        expr: sum(rate(http_requests_total[5m])) by (job)

4.3.2 评估并发控制

规则组之间串行执行,但组内规则并行执行。这意味着:

  • 一个规则组内的所有规则共享相同的评估时间点。
  • 如果组内某条规则执行缓慢,不会阻塞其他组。
  • 但组内规则之间会竞争查询资源。
最佳实践:将计算密集型的规则放在独立的规则组中,并设置较长的 interval,避免与高频规则互相影响。

4.3.3 评估延迟与超时

场景 表现 排查方法
评估耗时 > interval 规则组评估堆积,跳过后续评估 检查 prometheus_rule_group_last_duration_seconds
PromQL 超时 单条规则失败,记录错误 检查 prometheus_rule_evaluation_failures_total
TSDB 写入压力大 评估结果写入延迟 检查 prometheus_tsdb_storage_block_duration_seconds

4.4 阶段三:结果存储

评估完成后,Prometheus 将结果作为新的时间序列写入 TSDB。这一阶段涉及数据格式、压缩和索引更新。

4.4.1 写入流程

  1. 序列生成:根据规则 record 名称和 labels 生成唯一的 metric 标识。
  2. 样本追加:将 (timestamp, value) 对追加到 TSDB 的活跃内存块(head block)。
  3. 内存压缩:head block 达到阈值后,压缩为不可变块(block)并持久化到磁盘。
  4. 索引更新:更新倒排索引,使新序列可被查询。

4.4.2 存储特性

特性 说明 影响
样本去重 相同时间戳的样本只保留最后一个 避免重复写入导致数据膨胀
块压缩 使用 Gorilla 压缩算法 降低磁盘占用约 10 倍
写放大 压缩过程产生临时 I/O SSD 场景下影响较小
监控建议:
prometheus_tsdb_head_samples_appended_total — 活跃块追加样本数
prometheus_tsdb_compactions_total — 压缩操作次数
prometheus_tsdb_storage_blocks_bytes — 磁盘块大小

4.5 阶段四:数据过期

TSDB 根据 --storage.tsdb.retention.time 和 --storage.tsdb.retention.size 参数自动清理过期数据。

4.5.1 过期触发条件

  • 时间过期:块的最大时间戳超过保留期限(默认 15 天)。
  • 大小过期:TSDB 总大小超过保留上限(默认无限制)。
  • 手动触发:通过 API /api/v1/admin/tsdb/delete_series 删除指定序列。

4.5.2 过期流程

  1. 块标记:TSDB 后台协程定期扫描所有块,标记过期块。
  2. 块删除:标记的块从磁盘删除,释放空间。
  3. 索引清理:更新倒排索引,移除已删除序列的引用。
  4. WAL 截断:写前日志(WAL)中对应的记录被清理。
注意:Recording Rules 生成的数据与原始指标共享相同的保留策略。如果原始指标保留 7 天,预聚合结果也只保留 7 天。建议为预聚合结果设置独立的长期存储(如 Thanos、VictoriaMetrics)。

4.6 生命周期常见问题与排查

问题 可能原因 解决措施
规则评估结果缺失 评估超时 / 规则组被跳过 增加 interval 或优化 PromQL
预聚合数据延迟 TSDB 写入压力大 / 压缩阻塞 增加 TSDB 内存限制或扩容
磁盘空间暴涨 保留策略未生效 / 写放大 检查 retention 配置,调整压缩参数
规则加载失败 YAML 格式错误 / 文件路径错误 使用 promtool check rules 预校验
日常巡检命令:
promtool check rules /path/to/rules.yml — 校验规则文件语法
curl http://localhost:9090/api/v1/rules — 查看规则评估状态
curl http://localhost:9090/api/v1/status/tsdb — 查看 TSDB 存储状态

理解 Recording Rules 的完整生命周期,能够帮助你在规则延迟、数据丢失、存储异常等场景下快速定位根因。下一阶段将深入规则分组策略与评估间隔调优,进一步提升预聚合系统的稳定性与效率。