本篇是《Prometheus 从入门到生产实践》第 11 / 24 篇。配置以文中版本与环境前提为准,实验和故障均为教学场景。完整程序、配置及校验范围见配套实验包。

一条表达式在实验机上很快,不代表放到生产大盘每 15 秒刷新一次仍然合适。本篇学习定位查询开销,并把重复使用、语义稳定的计算做成 recording rules,而不是一遇到慢查询就先增加机器。
1. 查询成本不只由最终输出行数决定
sum(...) 最后只返回一个数,底层仍可能读取数百万条序列。粗略理解成本,可以观察:选中多少序列、每条读取多少历史样本、按多少求值点重复计算,以及是否包含昂贵的 join 或子查询。
一小时图每 15 秒求值,和一个月图每秒求值,工作量明显不同。把返回点数变少有助于传输和渲染,但不代表每一个点内部使用的窗口也变小。
2. 先拆查询,而不是直接改超时
当查询缓慢或报错,先固定时间范围,分别执行最内层选择器、rate、聚合和 join。记录每一步的结果数量和标签,查清哪一步把范围放大或产生重复匹配。
可以用下面表达式辅助理解选择规模,但它本身也是查询,不应对超大集群无节制反复执行:
count(ops_demo_requests_total{job="demo"})
再检查是否用了跨全部 job 的正则、无意保留 instance 或 pod、超长 range selector,以及多层高分辨率子查询。查询 timeout、最大样本数等限制是保护边界,调大之前应先解释实际需求。
Prometheus HTTP API 的查询结果可能带 warnings 或 infos。不要只检查 status=success 就丢掉这些诊断信息,尤其是混合直方图样本、不兼容运算或结果被移除时。
3. 什么时候值得用记录规则
同一五分钟 QPS 被十个面板和多个告警重复计算,可以预先生成一条新时间序列。recording rule 定期执行表达式,把结果按给定名字写入本地时序库。
收益是后续查询可直接使用稳定的中间结果;代价是新增计算、存储与规则维护。它不是免费缓存,也不自动为启用之前的历史补齐结果。
规则组一般按固定周期顺序执行。把有直接依赖的三条规则放在同一组,能够明确它们的求值顺序;不要假定不同组之间会按文件外观顺序形成可靠依赖。机制见 Recording rules 文档。
4. 一套包含缺失与无流量语义的记录规则
保存为 a-recording.rules.yml:
groups:
- name: demo-query-basics
interval: 30s
rules:
- record: job_route:ops_demo_requests:rate5m
expr: sum by (job, route) (rate(ops_demo_requests_total{job="demo"}[5m]))
- record: job_route:ops_demo_errors:rate5m
expr: sum by (job, route) (rate(ops_demo_requests_total{job="demo",code=~"5.."}[5m]))
- record: job_route:ops_demo_errors:ratio5m
expr: |
(
(
job_route:ops_demo_errors:rate5m
or on (job, route)
(0 * job_route:ops_demo_requests:rate5m)
)
/ on (job, route)
job_route:ops_demo_requests:rate5m
)
and on (job, route)
(job_route:ops_demo_requests:rate5m > 0)
第一条记录接口总 QPS;第二条记录错误 QPS;第三条计算比例。在已知总流量存在、错误序列缺失时补零;分母为零时不返回错误率,以保留“当前没有可定义的比例”这个状态。
job_route: 表达保留的维度,rate5m、ratio5m 表达计算与窗口。名字是团队约定,不是语法强制,但应让使用者知道它已经聚合到哪一层。后面直接对这个 rate 再求 rate,通常就用错了类型含义。
这份规则专门筛选 demo。生产中若环境或集群必须独立统计,应把它们纳入筛选或分组,不能照抄后把测试与生产流量混到一起。
5. 检查、引用和加载分别是三个动作
先检查规则,再把路径加入 Prometheus 配置的 rule_files,最后按既有流程重载。仅仅把 YAML 放进目录,不会自动生效。
promtool check rules a-recording.rules.yml
下列内容是加入已有 Prometheus 配置的片段,不是替换完整配置:
rule_files:
- a-recording.rules.yml
加载后查看 Rules 页面、规则求值健康和最近错误,再查询 job_route:ops_demo_requests:rate5m。若没有结果,区分输入不存在、窗口样本不足、规则未加载和计算失败。
6. 用确定的输入验证数学与标签
配套的 a-recording.test.yml 用每分钟 54 次正常、6 次错误的合成 counter,预期总 QPS 为 1、错误率为 0.1;另测只有正常序列时补零,以及没有请求时返回空比例。
promtool test rules a-recording.test.yml
这些是需要在自己的已安装版本上运行的测试命令,本篇不把文件存在等同于已经执行成功。完整测试文件在配套实验包中,语法可对照 规则测试文档。
synthetic 输入负责验证规则逻辑,不负责证明真实 exporter、采集网络和生产业务指标都正确。两类验证应分别保留记录。
7. 深一点:记录规则也会滞后和失败
一条五分钟 rate 规则每 30 秒求值,结果包含输入窗口与求值周期两层时间含义。面板使用它时,不会突然获得一秒级的新鲜度。
若一组规则执行时间接近甚至超过间隔,下一轮可能无法按预期及时完成。应监控规则求值持续时间、失败与错过迭代,并控制单组规模。把所有查询都预计算,并不一定比按需计算更省资源。
规则改名、改标签或改窗口会产生新的序列语义,历史面板、告警和远程写入依赖都要一起审查。长期规则应进入版本控制,附上测试和回滚方式。
8. 练习与验收
先比较原始 QPS 表达式与记录结果,允许求值时刻带来的差异;再把面板切到记录指标,观察查询开销和响应时间,而不是只凭主观感受判断“快了”。
最终验收至少包括:标签维度正确、单位与窗口清楚、正常和边界测试符合预期、规则健康、面板和告警引用更新完成。预计算的价值是把稳定语义复用起来,而不是给无法解释的查询换一个名字。
上一篇:聚合与向量匹配:on、group_left、缺失和除零 · 系列目录 · 下一篇:Grafana 与 SLO:正确展示、错误预算和多窗口燃尽