17.5.4 计算与比较操作:算术、逻辑与过滤
本节聚焦 PromQL 中的计算与比较操作,涵盖算术运算、逻辑运算与过滤语义的正确使用方式,帮助构建更精准的监控查询与告警表达式。
1. 算术运算(+ - * / % ^)#
规则要点
- 标量与向量运算:标量可与瞬时向量或区间向量结果进行运算,按样本逐点计算。
- 向量与向量运算:需满足标签匹配规则,默认按所有标签等值匹配;可通过 on() 或 ignoring() 指定匹配维度。
示例:使用率与速率折算
# 内存使用率(0~1)
1 - (node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes)
# HTTP 请求速率折算为每分钟
rate(http_requests_total[5m]) * 60
命令解释
- rate(metric[5m]):对 5 分钟区间求每秒增长速率。
- * 60:将“每秒”转为“每分钟”。
向量与向量:标签匹配
# 按 instance 匹配 CPU 与负载
rate(node_cpu_seconds_total{mode="idle"}[5m])
/ on(instance)
node_load1
2. 逻辑运算(and / or / unless)#
语义说明
- and:交集,返回两侧都存在的样本,保留左侧值。
- or:并集,返回任一侧存在的样本,两侧都有则优先左侧值。
- unless:差集,仅返回左侧存在且右侧不存在的样本。
示例
# 仅保留 up=1 且实例存在 CPU 指标的样本
up == 1 and on(instance) node_cpu_seconds_total
# 任意存在即可
up or node_cpu_seconds_total
# 仅保留没有磁盘读指标的实例(异常采集排查)
up == 1 unless on(instance) node_disk_read_bytes_total
3. 比较运算(== != > < >= <=)#
筛选语义
- 对向量进行过滤,仅保留满足条件的样本(不改变样本值)。
示例:阈值过滤与布尔比较
# 磁盘可用率低于 20%
node_filesystem_avail_bytes / node_filesystem_size_bytes < 0.2
# 显式返回 0/1 的布尔比较
(up == 1) bool
命令解释
- bool:返回 0/1 结果,便于后续计算或作为条件。
4. 过滤与标签匹配#
标签选择器过滤
# 等值
node_cpu_seconds_total{job="node"}
# 正则
node_cpu_seconds_total{instance=~"10\\.0\\.1\\..*"}
# 排除
node_cpu_seconds_total{job!="node",instance!~"192\\.168\\..*"}
多对一/一对多匹配
# 将 pod 的 CPU 指标关联到 node 标签
rate(container_cpu_usage_seconds_total[5m])
* on(pod) group_left(node)
kube_pod_info
5. 安装与快速验证(Prometheus + promtool)#
用于本节示例的可运行环境,可在本机快速搭建 Prometheus。
Docker 一键运行
# 运行 Prometheus(含默认本机自采集)
docker run -d --name prom \
-p 9090:9090 \
prom/prometheus
# 访问
# http://localhost:9090
promtool 安装与解释
# 下载并解压(Linux x86_64)
wget https://github.com/prometheus/prometheus/releases/download/v2.50.0/prometheus-2.50.0.linux-amd64.tar.gz
tar -xf prometheus-2.50.0.linux-amd64.tar.gz
cd prometheus-2.50.0.linux-amd64
# 使用 promtool 验证表达式(返回语法错误或成功)
./promtool check rules /path/to/rules.yml
6. 排错与常见问题#
问题 1:结果为空
可能原因:标签匹配不一致,或默认按全部标签匹配导致没有交集。
解决方法:用 on()/ignoring() 指定匹配维度。
问题 2:值异常为 NaN
可能原因:除数为 0 或向量缺失。
解决方法:加入过滤或使用 clamp_min() 保护。
示例修复
# 避免除 0
rate(http_requests_total[5m]) / clamp_min(rate(http_requests_total[5m]), 1)
7. 练习(含预期效果)#
练习 1:计算实例 CPU 使用率(非 idle)
1 - avg by(instance) (rate(node_cpu_seconds_total{mode="idle"}[5m]))
预期效果:返回每个实例的 CPU 使用率(0~1)。
练习 2:筛选 5 分钟内网络入站速率 > 10MB/s 的实例
rate(node_network_receive_bytes_total[5m]) > 10 * 1024 * 1024
预期效果:仅返回满足阈值的时间序列。
练习 3:找出“up=1 但缺失磁盘指标”的实例
up == 1 unless on(instance) node_disk_read_bytes_total
预期效果:提示采集异常或 Exporter 缺失的实例。
8. 实践注意事项#
- 运算两侧时间序列数量差距较大时,使用
on()/ignoring()精准控制匹配,避免意外丢失数据。 - 逻辑运算更适合用于存在性判断与数据集过滤,不用于计算数值。
- 比较运算用于告警条件时,建议明确阈值单位与时间窗口,避免短时尖峰误报。