4. PromQL 运算与函数:算术、比较、逻辑与四大速率函数

PromQL 不仅是查询语言,更是一套强大的时序数据处理引擎。本章将深入解析 PromQL 的三大运算类型(算术、比较、逻辑)以及四个最核心的速率/增量函数(rate、irate、increase、delta、idelta)。掌握这些运算与函数,是设计黄金指标录制规则的基础。

4.1 算术运算:指标间的数值变换

算术运算符用于对两个时序向量或一个向量与一个标量进行数学计算。所有运算符均遵循 瞬时向量匹配规则(一对一匹配)。

运算符 含义 典型场景
+ 加法 合并两个指标的值
- 减法 计算差值(如总内存 - 空闲内存)
* 乘法 单位换算(如 CPU 秒 → 毫秒)
/ 除法 计算比率(如请求错误率)
% 取模 判断数值周期性
^ 幂运算 指数级放大/缩小
实战案例: 计算 CPU 使用率百分比
(1 - avg(rate(node_cpu_seconds_total{mode="idle"}[5m])) by (instance)) * 100

说明:先用 1 - idle 比例 得到使用率,再乘以 100 转换为百分比。

4.2 比较运算:触发告警的布尔逻辑

比较运算符返回布尔结果(0 或 1),常用于告警规则中的阈值判断。支持 ==、!=、>、<、>=、<=。

比较运算有两种模式:

  • 过滤模式(默认):保留满足条件的时序,不满足的丢弃。
  • 布尔模式:使用 bool 修饰符,返回 0 或 1,保留所有时序。
关键区别:
http_requests_total > 100 → 只返回 > 100 的时序。
http_requests_total bool > 100 → 返回所有时序,满足为 1,不满足为 0。

4.3 逻辑运算:组合多个条件

逻辑运算符用于组合多个瞬时向量选择器,仅适用于瞬时向量。

运算符 含义 说明
and 交集 返回两边都存在的时序(以左侧为准)
or 并集 返回左侧所有时序 + 右侧左侧不存在的时序
unless 差集 返回左侧存在但右侧不存在的时序
注意: 逻辑运算不进行向量匹配,只基于标签集合判断存在性。例如 up{job="api"} and on(instance) up{job="db"} 表示同时运行 api 和 db 的实例。

4.4 四大速率与增量函数

这五个函数是 PromQL 中最常用、最容易混淆的核心函数。它们都作用于范围向量,但计算逻辑和适用场景截然不同。

4.4.1 rate() vs irate():平均速率 vs 瞬时速率

函数 计算方式 特点 适用场景
rate() 区间内总增量 / 区间时长 平滑、抗抖动 长期趋势、告警、录制规则
irate() 区间内最后两个样本的差值 / 时间差 灵敏、反映瞬时突增 实时监控、短时间窗口仪表盘
对比示例:
# 5分钟平均每秒请求数(平滑)
rate(http_requests_total[5m])

# 最后两个数据点之间的瞬时每秒请求数(灵敏)
irate(http_requests_total[5m])

在录制规则中,优先使用 rate(),因为 irate() 对采样间隔敏感,容易产生毛刺。

rate() vs irate() 计算逻辑对比 rate() — 平均速率 区间 [t₀, t₅] 内 总增量 / 区间时长 样本点: v₀, v₁, v₂, v₃, v₄, v₅ rate = (v₅ - v₀) / (t₅ - t₀) ✅ 平滑,抗采样抖动 ✅ 适合录制规则与告警 irate() — 瞬时速率 区间 [t₀, t₅] 内 最后两个样本的差值 / 时间差 样本点: v₀, v₁, v₂, v₃, v₄, v₅ irate = (v₅ - v₄) / (t₅ - t₄) ⚡ 灵敏,反映瞬时突增 ⚠️ 对采样间隔敏感,易毛刺

4.4.2 increase():区间内的增量

increase() 返回范围向量中计数器的增加值。它本质上是 rate() * 区间秒数 的近似值,但更直观。

典型用法:
# 过去1小时内处理的请求总数
increase(http_requests_total[1h])

# 过去5分钟内发生的错误次数
increase(errors_total[5m])

注意:increase() 也适用于 gauge 类型,但通常只用于计数器。

4.4.3 delta() vs idelta():仪表盘的变化量

这两个函数专门用于 gauge(仪表盘) 类型指标,计算数值的变化量。

函数 适用类型 计算方式 典型场景
delta() gauge 区间内最后一个值 - 第一个值 温度变化、内存使用变化
idelta() gauge 区间内最后两个样本的差值 瞬时变化量检测
重要区别:
delta(memory_usage_bytes[5m]) → 5 分钟内的总变化量。
idelta(memory_usage_bytes[5m]) → 最后两个采集点之间的变化量(通常只有几秒)。
在录制规则中,delta() 更常用,idelta() 仅用于需要极灵敏检测的场景。
四大速率/增量函数适用场景矩阵 函数 适用指标类型 输出含义 推荐录制规则 rate() Counter 每秒平均速率 ✅ 强烈推荐 irate() Counter 瞬时每秒速率 ⚠️ 仅仪表盘 increase() Counter 区间增量 ✅ 推荐 delta() Gauge 区间变化量 ✅ 推荐

4.5 录制规则设计中的函数选择原则

在录制规则中,函数选择直接影响规则的稳定性、存储成本和告警准确性。以下是经过生产验证的选择原则:

  1. 优先使用 rate() 而非 irate():录制规则需要平滑的基线,rate() 的抗抖动特性更适合长期存储。
  2. increase() 用于“总量”场景:当业务需要“过去 X 分钟发生了多少次”时,increase() 比 rate() 更直观。
  3. delta() 用于 gauge 变化量:监控内存、磁盘等资源的变化趋势时,delta() 是标准选择。
  4. 避免在录制规则中使用 idelta():idelta() 的瞬时性会导致录制规则结果频繁跳变,增加存储噪音。
  5. 比较运算 + bool 修饰符用于告警规则:在告警规则中,使用 bool 可以保留所有时序,便于多条件组合。
最佳实践: 在录制规则中,将原始指标通过 rate() 或 delta() 转换为每秒速率或区间变化量,再与阈值进行比较。这样既降低了 PromQL 复杂度,又提高了告警规则的复用性。