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() 精准控制匹配,避免意外丢失数据。
  • 逻辑运算更适合用于存在性判断与数据集过滤,不用于计算数值。
  • 比较运算用于告警条件时,建议明确阈值单位与时间窗口,避免短时尖峰误报。