跳到主要内容

记录规则

通过 PromQL 可以实时对 Prometheus 中采集到的样本数据进行查询,聚合以及其它各种运算操作。而在某些 PromQL 较为复杂且计算量较大时,直接使用 PromQL 可能会导致 Prometheus 响应超时的情况。这时需要一种能够类似于后台批处理的机制在后台完成这些复杂运算的计算,对于使用者而言只需要查询这些运算结果即可。Prometheus 通过 Recoding Rule 规则支持这种后台计算的方式,可以实现对复杂查询的性能优化,提高查询效率。这对于 Grafana Dashboard 特别有用,仪表板每次刷新时都需要重复查询相同的表达式。

配置

在 Prometheus 配置文件中,我们可以通过 rule_files 定义 recoding rule 规则文件的访问路径。

rule_files: [- <filepath_glob> ...]

每一个规则文件通过以下格式进行定义:

groups: [- <rule_group>]

一个简单的规则文件可能是这个样子的:

groups:
- name: example
rules:
- record: job:http_inprogress_requests:sum
expr: sum(http_inprogress_requests) by (job)

rule_group 的具体配置项如下所示:

# 分组的名称,在一个文件中必须是唯一的
name: <string>

# 评估分组中规则的频率
[ interval: <duration> | default = global.evaluation_interval ]

rules:
[ - <rule> ... ]

与告警规则一致,一个 group 下可以包含多条规则。

# 输出的时间序列名称,必须是一个有效的 metric 名称
record: <string>
# 要计算的 PromQL 表达式,每个评估周期都是在当前时间进行评估的,结果记录为一组新的时间序列,metrics 名称由 record 设置
expr: <string>
# 添加或者覆盖的标签
labels: [<labelname>: <labelvalue>]

根据规则中的定义,Prometheus 会在后台完成 expr 中定义的 PromQL 表达式计算,并且将计算结果保存到新的时间序列 record 中,同时还可以通过 labels 标签为这些样本添加额外的标签。

这些规则文件的计算频率与告警规则计算频率一致,都通过 global.evaluation_interval 进行定义:

global: [evaluation_interval: <duration> | default = 1m]

测试

比如现在我们想要获取空闲节点内存的百分比,可以使用如下所示的 PromQL 语句查询:

100 - (100 * node_memory_MemFree_bytes / node_memory_MemTotal_bytes)

查询结果

然后现在我们就可以使用记录规则将上面的表达式重新配置。同样在配置报警规则的 groups 下面添加如下所示配置:

groups:
- name: recording_rules
rules:
- record: job:node_memory_MemFree_bytes:percent
expr: 100 - (100 * node_memory_MemFree_bytes / node_memory_MemTotal_bytes)
# 其他报警规则
- name: test-node-mem
rules: # 具体的报警规则
- alert: NodeMemoryUsage # 报警规则的名称
......

这里其实相当于我们为前面的查询表达式配置了一个 job:node_memory_MemFree_bytes:percent 的别名,一般来说记录规则的名称可以使用:字符来进行连接,这样的命名方式可以让规则名称更加有意义。更新上面配置并 reload 下 Prometheus 即可让记录规则生效,在 Prometheus 的 Rules 页面正常也可以看到上面添加的记录规则:

记录规则

现在我们就可以直接使用记录规则的名称 job:node_memory_MemFree_bytes:percent 来进行查询了:

记录规则名称

由于我们这里的查询语句本身不消耗资源,所以使用记录规则来进行查询差距不大,但是对于需要消耗大量资源的查询语句则提升会非常明显。