共计 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
可以引申两个问题:
- 多个范围向量选择器
这是因为 *_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
参数进行评估内部表达式。
-
复杂 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
效果图:
导出为 excel :
总结
recording rules 在简化 pql 语法时非常有用,同时可以提高性能。查询预计算结果通常比需要时进行计算表达式快得多。
grafana 也是监控利器,各种类型的图表组合使用绘制 dashboard 可以解决很多问题。
本文属于专题:Prometheus 监控
- 使用 Redis Exporter 监控 Redis
- Grafana 备份、迁移与升级
- 云原生监控 Kube-Prometheus
- Prometheus 集成 Nginx 监控
- Prometheus 查询指定时间范围内的峰值或均值
- 云监控接入本地Prometheus
- 使用 MySQL Exporter 监控MySQL
- 个人微信接收夜莺告警消息
- PushGateway 报错:too many open files
- Blackbox 网络监控
- node_exporter 添加自定义指标
- Python 实现资源水位巡检
- Prometheus 替代方案:VictoriaMetrics
- 使用 node_exporter 实现路由器监控