4. PromQL 二元运算符:算术、比较与逻辑/集合
在 PromQL 中,二元运算符用于连接两个即时向量或标量,生成新的结果。理解这三类运算符的优先级、匹配机制与使用场景,是编写正确告警表达式的基础。本章按运算符类型逐一拆解,并重点说明向量匹配规则。
4.1 运算符分类总览
| 类别 | 运算符 | 作用 | 典型告警场景 |
|---|---|---|---|
| 算术运算符 | + - * / % ^ |
数值计算 | 计算 CPU 空闲率、内存使用率、错误占比 |
| 比较运算符 | == != > < >= <= |
条件过滤,返回 0 或 1 | 阈值告警触发条件 |
| 逻辑/集合运算符 | and or unless |
集合交、并、差 | 多条件组合告警、排除特定实例 |
优先级规则: 算术 > 比较 > 逻辑。同一优先级内从左到右结合。建议使用括号
() 显式控制计算顺序,避免歧义。
4.2 算术运算符:向量与标量的计算
算术运算符支持 标量-标量、向量-标量 和 向量-向量 三种组合。在告警表达式中,最常用的是向量-标量运算(如计算百分比)和向量-向量运算(如计算两个指标的比例)。
# 向量-标量:计算 CPU 使用率(百分比)
100 - (avg by(instance) (rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100)
# 向量-向量:计算请求错误率
rate(http_requests_total{status=~"5.."}[5m])
/
rate(http_requests_total[5m])
关键点: 向量-向量运算时,PromQL 默认使用 一对一匹配,要求左右两侧向量具有完全相同的标签集合。如果标签不一致,需要使用
on / ignoring 关键字调整匹配规则。
4.3 比较运算符:告警触发条件
比较运算符在 PromQL 中返回 布尔值(0 或 1)。当用于 即时向量 时,它会过滤掉不满足条件的样本,只保留结果为 1 的序列。这是告警规则中 expr 字段的核心机制。
# 触发条件:CPU 使用率超过 90%
(100 - (avg by(instance) (rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100)) > 90
# 触发条件:内存可用量低于 512MB
node_memory_MemAvailable_bytes / 1024 / 1024 < 512
比较运算符支持 bool 修饰符,强制返回 0 或 1 而不过滤样本,适用于需要保留所有序列但标记状态的场景。
# 使用 bool 修饰符:所有实例都返回 0 或 1,不丢弃任何序列
http_requests_total > bool 1000
4.4 逻辑/集合运算符:多条件组合
逻辑运算符作用于 即时向量,基于标签集合进行集合运算。在告警表达式中,常用于组合多个条件或排除特定实例。
| 运算符 | 含义 | 告警场景示例 |
|---|---|---|
and |
交集:结果包含同时出现在左右两侧的序列 | CPU 高 且 内存高 |
or |
并集:结果包含出现在左侧或右侧的序列 | 磁盘使用率高 或 inode 使用率高 |
unless |
差集:结果包含在左侧但不在右侧的序列 | 所有实例 排除 特定维护实例 |
# and 示例:CPU 高且内存高
(avg by(instance) (rate(node_cpu_seconds_total{mode="idle"}[5m])) < 0.1)
and
(node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes < 0.2)
# unless 示例:排除实例 "web-01" 的告警
node_load1 > 5 unless on(instance) node_load1{instance="web-01"}
常见陷阱: 逻辑运算符不进行数值计算,只做集合操作。例如
up == 0 and up{job="api"} 不会返回数值 0,而是返回标签匹配的序列。确保左右两侧的标签集合一致,否则结果可能为空。
4.5 向量匹配机制:一对一、多对一与 group 修饰符
当二元运算符连接两个向量时,PromQL 需要确定如何匹配标签。理解匹配机制是避免告警表达式返回空结果的关键。
匹配规则速记:
- 默认一对一: 左右标签完全一致,无需额外关键字。
- on(标签列表): 只使用指定标签进行匹配,忽略其他标签。
- ignoring(标签列表): 忽略指定标签,使用其余标签匹配。
- group_left / group_right: 多对一或一对多匹配时使用,左侧/右侧保留所有标签。
4.6 运算符优先级与括号使用
PromQL 运算符优先级从高到低为:^ > * / % > + - > == != > < >= <= > and or unless。同一优先级内从左到右结合。
# 不加括号的潜在问题:比较运算符优先级低于算术
# 期望:CPU 使用率 > 90%
# 实际:先计算 100 - avg(...) * 100,再与 90 比较
100 - avg by(instance) (rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100 > 90
# 正确写法:使用括号明确计算顺序
(100 - (avg by(instance) (rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100)) > 90
告警表达式复核要点: 在复核告警规则时,务必检查二元运算符的优先级是否与业务逻辑一致。常见错误包括:忘记括号导致比较条件提前计算、向量匹配标签不一致导致结果为空、逻辑运算符误用为数值计算。建议在 Prometheus 的 Graph 页面中先用
query_range 验证表达式结果,再写入告警规则。