Prometheus 查询指定时间范围内的峰值或均值

1,716次阅读
没有评论

共计 2963 个字符,预计需要花费 8 分钟才能阅读完成。

背景

公司近日需要统计云服务资源的利用率,例如云服务器产品。

我们有自建基于 prometheus 的监控系统,实时抓取存储了服务器的监控指标。

但是利用率如何衡量?单说CPU使用率,我们是应该取均值还是峰值?

商量后,计划先利用原始数据(实时值)同时计算出峰值和均值,两个指标同时作为参考。

但是在写prom ql时,遇到了一些障碍。

recording rules

以最简单的 prom ql​ 示例,统计当前时刻的CPU 使用率 和 内存使用率。

ps:host_name, host_ip 为自定义的lable,avg是用于给数据按 lable 分组。

CPU 使用率:

1 - avg(irate(node_cpu_seconds_total{mode="idle"}[5m])) by (host_name, host_ip)

内存使用率:

1 - node_memory_MemAvailable_bytes{mode!="idle"} / node_memory_MemTotal_bytes

假如我们期望在获取某个范围内的值,需要利用到子查询,子查询有以下四种:

  • avg_over_time() #指定间隔内所有点的平均值。
  • min_over_time() #指定间隔中所有点的最小值。
  • max_over_time() #指定间隔内所有点的最大值。
  • sum_over_time() #指定时间间隔内所有值的总和。

需求是期望获得最大值和均值,所以可以使用 max_over_time 和 avg_over_time。以 max_over_time 为例,常规思路来说,上述 pql 需要改写为如下形式:

CPU 使用率:

max_over_time(1 - avg(irate(node_cpu_seconds_total{mode="idle"}[5m])) by (host_name, host_ip)[24h])

内存使用率:

max_over_time(1 - node_memory_MemAvailable_bytes{mode!="idle"} / node_memory_MemTotal_bytes)[24h]

然而执行查询时,会发现 pql 报错:

bad_data: 1:94: parse error: ranges only allowed for vector selectors

可以引申两个问题:

  1. 多个范围向量选择器

    这是因为 *_over_time() 函数都需要输入一个范围向量,范围向量通常只能由单个区间向量选择器产生,比如 test_metric[5m]。

    但是我们现在的需求是,使用 max_over_time() 函数来找出24h内的CPU MAX值。

    从上述 pql 中可见,CPU使用率不是一个原始值,而是通过 irate 函数计算的,已经包含了范围向量[5m],我们应该如何再增加 24h 的向量选择器?

    如果是单一指标的查询,不涉及加减乘除等数学运算,可以这样写

    max_over_time(irate(node_cpu_seconds_total{mode="idle",host_ip="10.76.36.255"}[5m])[24h:])
    

    上述 pql 的含义是,首先以指定的步长在 5m 内执行内部查询,然后根据子查询的结果计算外部查询。

    子查询的表示方式类似于区间向量的持续时间,但需要冒号后添加了一个额外的步长参数:[duration:resolution]

    resolution​ 表示步长参数,省略时Prometheus 会使用配置的全局 evaluation\_interval​ 参数进行评估内部表达式。

  2. 复杂 pql 套用 *_over_time() 计算语法问题

    当 pql 中存在加减乘除等数学运算时,使用上述解决办法(增加步长)的 pql 会报另一个错误:

    # pql
    max_over_time(1 - avg(irate(node_cpu_seconds_total{mode="idle"}[5m])) by (host_name, host_ip)[24h:1m])
    
    # error
    bad_data: 1:19: parse error: binary expression must contain only scalar and instant vector types
    

recording rules​ 允许预先计算经常需要的,或者计算复杂度高的表达式,并将结果保存为一组新的时间序列数据。

所以我们可以利用它,将原本的 pql 转换为指标,然后针对这个指标再进行子查询,降低复杂度,也避免了语法问题。

参考链接:

知乎:Prometheus基础相关–PromQL 基础(2)

prometheus.io querying/functions

prometheus 配置 rules

prometheus 支持的 rules 有两类,一类是 recording rules​ ,另一类是 alerting rules​。此处不展开赘述 alerting rules​。

编辑 prometheus.yml​ , 增加 配置 rules 路径。

rule_files:
  - /etc/prometheus/rules/*.yml

写入 rules 规则,编辑 rules/node_exporter.yml

groups:
  - name: node_exporter_recording_rule
    rules:
    - record: irate_node_cpu_usage_percent_5m
      expr: 1 - irate(node_cpu_seconds_total{mode="idle"}[5m])
    - record: node_memory_usage_percent
      expr: 1 - node_memory_MemAvailable_bytes{mode!="idle"} / node_memory_MemTotal_bytes

完毕后 reload prometheus,以使配置生效。

在一个 scrape_interval​ 周期后,prometheus 内将能够直接以上述 recording后的 metrics 进行查询。

此时这两条 pql 是等价的

# 原始pql
1 - irate(node_cpu_seconds_total{mode="idle"}[5m])

# recording metric
irate_node_cpu_usage_percent_5m

此时我们使用 max_over_time() 函数进行子查询即可得到期望的结果:

avg(
    max_over_time(
        irate_node_cpu_usage_percent_5m[24h:]
    )
) 
by (host_name,host_ip)

grafana 绘制面板

使用 table 类型的图标,可以直观呈现数据,并且能够导出 excel 表格。本文不展开赘述具体如何绘制图表。

大概流程为如下:

  • Query部分
    • pql 语句编写
    • 配置为 table 类型的query
  • Transform部分
    • Merge
    • Organize fields
  • Panel部分
    • Add override property

效果图:

Prometheus 查询指定时间范围内的峰值或均值

导出为 excel :

Prometheus 查询指定时间范围内的峰值或均值

总结

recording rules 在简化 pql 语法时非常有用,同时可以提高性能。查询预计算结果通常比需要时进行计算表达式快得多。

grafana 也是监控利器,各种类型的图表组合使用绘制 dashboard 可以解决很多问题。

本文属于专题:Prometheus 监控

引用链接

正文完
 21
pengyinwei
版权声明:本站原创文章,由 pengyinwei 2023-11-15发表,共计2963字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处:https://www.opshub.cn
评论(没有评论)