Recording Rules

Recording rules

有一些监控的数据查询时很耗时的,还有一些数据查询所使用的查询语句很繁琐。Recording rules 可以把一些很耗时的查询或者很繁琐的查询进行提前查询好,然后在需要数据的时候就可以很快拉出数据。譬如:

# 规则分组 rule_group,不论是 recording rules 还是 alerting rules 都要在组里面
groups:
  # groups的名称
  - name: example
    #该组下的规则
    rules:
      [ - <rule> ... ]

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

groups:
 - name: example
   rules:
    - record: job:process_cpu_seconds:rate5m
      expr: sum without(instance)(rate(process_cpu_seconds_total[5m]))
    - record: job:process_open_fds:max
      expr: max without(instance)(process_open_fds)

语法校验

完整的规则语法如下:

groups:
  [ - <rule_group> ]

<rule_group>的语法
# 规则组名 必须是唯一的
name: <string>

# 规则评估间隔时间
[ interval: <duration> | default = global.evaluation_interval ]

rules:
  [ - <rule> ... ]

<rule>的语法
# 收集的指标名称
record: <string>

# 评估时间
# evaluated at the current time, and the result recorded as a new set of
# time series with the metric name as given by 'record'.
expr: <string>

# Labels to add or overwrite before storing the result.
labels:
  [ <labelname>: <labelvalue> ]

要在不启动 Prometheus 进程的情况下快速检查规则文件是否在语法上正确,可以通过安装并运行 Prometheus 的 promtool 命令行工具来校验:

$ go get github.com/prometheus/prometheus/cmd/promtool

案例

减少基数

如果我们有如下的表达式:

$ sum without(instance)(rate(process_cpu_seconds_total{job="node"}[5m]))

如果直接在 Dashboard 中输入如上的 PromQL,在数据量较大的情况下,极有可能会导致过长的计算时间。我们可以使用如下的记录规则来构建新的指标:

groups:
  - name: node
    rules:
      - record: job:process_cpu_seconds:rate5m
        expr: >
          sum without(instance)(
            rate(process_cpu_seconds_total{job="node"}[5m])
          )          

现在,您只需要在渲染仪表板时获取一个时间序列即可,即使正在播放检测标签,也能快速地返回结果,因为您将要处理的时间序列数减少了多少个实例。实际上,您正在以持续资源成本进行交易,而查询的延迟和资源成本却大大降低。由于这种折衷,使用长向量范围的规则通常是不明智的,因为这样的查询往往很昂贵,并且定期运行它们会导致性能问题。您应该尝试将一项工作的所有规则归为一组。这样,它们将具有相同的时间戳,并在您对它们进行进一步的数学运算时避免出现失真。一组中的所有记录规则对于执行都具有相同的查询评估时间,并且所有输出样本也将具有该时间戳。您通常会有基于相同度量标准但具有不同标签集的聚合规则。通过让一个规则使用另一个规则的输出,您可以提高效率,而不是单独计算每个聚合。例如:

groups:
  - name: node
    rules:
      - record: job_device:node_disk_read_bytes:rate5m
        expr: >
          sum without(instance)(
            rate(node_disk_read_bytes_total{job="node"}[5m])
          )          
      - record: job:node_disk_read_bytes:rate5m
        expr: >
          sum without(device)(
            job_device:node_disk_read_bytes:rate5m{job="node"}
          )          

组合 Range Vector 函数

如前所述,不能在产生即时矢量的函数的输出上使用范围矢量函数,譬如 max_over_time(sum without(instance)(rate(x_total[5m]))[1h]) 这样的操作就是不可行的。我们可以利用 Recording Rules 实现这样的功能:

groups:
  - name: j_job_rules
    rules:
      - record: job:x:rate5m
        expr: >
          sum without(instance)(
            rate(x_total{job="j"}[5m])
          )          
      - record: job:x:max_over_time1h_rate5m
        expr: max_over_time(job:x:rate5m{job="j"}[1h])

此方法可与任何范围向量函数一起使用,不仅包括 _over_time 函数,而且包括 predict_linear,deriv 和 holt_winters。但是,此技术不应与 rate, irate, 或者 increase 一起使用,因为有效的速率表达 (sum(x_total)[5m]) 每次其组成计数器之一重置或消失时都会产生大量尖峰。

上一页
下一页