记录规则
夜莺 v9 记录规则(Recording Rule):把复杂高基数 PromQL 预聚合成新指标,让告警和仪表盘查询从分钟级降到秒级。
概述
记录规则(Recording Rule) = 按固定频率提前跑一段 PromQL,把结果写成新指标回存,告警/仪表盘后续查这个新指标即可,省掉每次重算的开销。
侧栏路径:数据查询 → 指标 → 记录规则 Tab,URL /recording-rules。
为什么需要它?复杂查询(多 join、高基数 sum、histogram_quantile)每次执行都很重。如果:
- 同一个查询被多个告警规则、多个仪表盘反复用;
- 查询本身慢(几秒甚至几十秒);
- 长 range(
[1h]、[1d])的查询,每分钟告警判定时都要回算;
把它做成记录规则,每分钟(或你指定的频率)预算一次,结果作为新指标存起来。后续告警/仪表盘只查这个轻量新指标,毫秒级返回。
经典场景:
node:cpu:usage_pct=100 - (avg by (instance) (rate(cpu_idle[5m])) * 100),给告警和大盘共用;service:http_latency:p99_5m=histogram_quantile(0.99, sum by (service, le) (rate(http_duration_bucket[5m]))),所有告警都基于这个;business:order_success_rate:1m= 业务指标,跨多个数据源 join 后归一化。
新建 / 编辑记录规则
表单分四块:
① 基础配置
| 字段 | 必填 | 说明 |
|---|---|---|
| 业务组 | 是 | 规则归属,做权限隔离 |
| 备注 | 否 | 简短描述这条规则的用途,方便团队协作 |
| 附加标签 | 否 | key=value 格式,写入新指标的额外标签。例如附加 team=infra,方便后续过滤 |
② 指标配置:定义产出什么新指标
每个"指标配置"块产出一条新指标。可以加多个块,一条规则同时写多个指标。
| 字段 | 必填 | 说明 |
|---|---|---|
| 回写数据源 开关 | 默认开 | 关掉后规则只在内存里跑(用于调试),不实际产出指标 |
| 查询条件 A / B / … | 至少 1 个 | 定义一个或多个 PromQL,每个有自己的数据源类型 + 数据源 + 查询语句 |
| 新指标名称 | 是 | 产出指标的 metric name,Prometheus 命名约定推荐:<level>:<metric>:<operations>,如 node:cpu:usage_pct |
| 计算表达式 | 是 | 引用前面查询条件的结果做合成。默认 $A 即直接用 A 的结果;可以写 $A / $B * 100 这种二次计算 |
| 目标时序源 | 是 | 新指标写到哪个 Prometheus 兼容数据源 |
③ 多查询 + 跨数据源
「添加指标配置」按钮可以再加一块,一条记录规则同时产出多个指标 — 适合"一次抓数据,产出多个衍生指标"的场景。
如果在指标配置里加多个查询条件(A、B、C),还能做跨数据源 join:A 来自 Prometheus、B 来自 MySQL,计算表达式 $A * $B 把两边数据相乘 — 不过这种用法谨慎,性能不一定比直接联邦更好。
④ 其他配置
| 字段 | 说明 |
|---|---|
| 执行频率 | cron 表达式,默认 @every 15s。不要比原始指标的抓取频率短 — 比如指标本身 15s 一个点,记录规则 5s 跑一次没意义。常用值:@every 1m / @every 15s |
实操:把慢告警查询替换成记录规则
举个常见例子。原本一条告警查:
histogram_quantile(0.99, sum by (service, le) (rate(http_duration_seconds_bucket[5m]))) > 1
这个查询基数高 + range 长,告警引擎每 30s 跑一次很重。改造步骤:
- 来
/recording-rules/add,新建一条规则; - 新指标名称:
service:http_latency:p99_5m; - 查询条件 A:填上面那串 PromQL(不带
> 1阈值); - 计算表达式:
$A; - 目标时序源:选告警引擎能查到的数据源;
- 执行频率:
@every 30s(和告警判定同频); - 保存。
新建完后稍等一会(够跑一次),去 即时查询 验证 service:http_latency:p99_5m{} 有数据。
最后回告警规则里把 PromQL 改成 service:http_latency:p99_5m > 1 — 查询直接从一个轻量指标里读,告警判定毫秒级搞定。
常见问题
Q1:记录规则配好了但是查不到新指标?
A:按顺序排查:
- 等够一个执行周期(默认 15s,最长 1m);
- 「数据预览」按钮看 PromQL 是否能查出原始数据 — 查不出说明源 PromQL 本身有问题;
- 检查"目标时序源"是不是支持 remote_write(绝大多数 Prometheus 兼容数据源都支持,但 PromQL 只读的网关可能不支持);
- 看夜莺 Server 日志有没有
recording rule eval failed之类的错误; - 检查记录规则的「启用」开关是否打开。
Q2:记录规则的执行频率怎么选最合适?
A:建议和告警判定频率对齐,且不短于原始指标抓取频率:
- 原始抓取 15s + 告警判定 30s → 记录规则
@every 30s最佳; - 抓取 1m + 告警判定 1m → 记录规则
@every 1m; - 想做秒级告警?得先把原始指标抓取频率也提到秒级,否则记录规则跑再快也是相同的数据点。
Q3:能不能写一条记录规则用于历史回填?
A:不能。记录规则只对"未来的数据"生效 — 从启用那一刻开始按频率产出。历史区间内没有新指标。如果需要回填,思路是:
- 在原始数据源上用 PromQL 直接查(速度慢点也认了);
- 或用 VictoriaMetrics 的 vmalert 离线模式 跑历史回填。
Q4:高基数指标做记录规则会不会反而更慢?
A:会 — 如果做错了。记录规则要主动降基数:
- 用
sum by (维度子集):把上百个标签收敛到只保留关键的几个; - 别保留
instance/pod这种瞬变标签(除非业务必需); - 输出的新指标 series 数应该比输入少 1-2 个数量级。
否则记录规则只是把"查询慢"变成"写入慢 + 查询稍快"。