PromQL 查询 Prometheus 指标的常用语法

FreeGuideOnline 最新 2026-07-08

promql node_cpu_seconds_total

可配合 `{}` 进行标签过滤。支持以下匹配操作符:
- `=`:精确匹配
- `!=`:不等于
- `=~`:正则匹配
- `!~`:正则不匹配

```promql
# 查询 job 为 "node" 且 cpu 为 "0" 的指标
node_cpu_seconds_total{job="node", cpu="0"}

# 查询 mode 以 "idle" 结尾的指标
node_cpu_seconds_total{mode=~".*idle"}

标签选择器也可以通过逗号分隔并列,表示“且”的逻辑。使用 or 操作符可以表达“或”。

范围向量与偏移

为指标附加时间窗口可以获得一段历史样本,用于速率计算等场景:

# 过去 5 分钟内的所有样本
node_cpu_seconds_total[5m]

offset 修饰符允许你查询某个时间点之前的数据,常用于同比对比:

# 查询 1 小时前对应时刻的 5 分钟范围数据
node_cpu_seconds_total[5m] offset 1h

瞬时向量也可以使用 offset:

node_cpu_seconds_total offset 1h

核心操作符

算术与比较

PromQL 支持标准的 +-*/%^。当对两个瞬时向量运算时,会按照左侧指标中的标签集合进行一对一匹配。若左右标签不同,需要使用 on()ignoring() 指明匹配方式。

# 计算每种 mode 占 CPU 时间比例
node_cpu_seconds_total / ignoring(cpu) sum without(cpu)(node_cpu_seconds_total)

比较操作符 ==!=><>=<= 常用于过滤:

# 找出请求总数大于 100 的实例
http_requests_total > 100

集合与逻辑操作

  • and:左右向量都存在的标签组合
  • or:合并左右向量的标签组合
  • unless:左边存在但右边不存在的标签组合

这些操作符常用于告警规则或复杂过滤,遵循向量匹配规则。

聚合操作

聚合将多条时间序列压缩为一条或多条。常用聚合函数:

  • summinmaxavgstddevcount
  • topk(k, expr):前 k 个最大值
  • bottomk(k, expr):后 k 个最小值
  • quantile(φ, expr):φ 分位数

必须配合 bywithout 指定聚合的维度,否则可能将所有实例合并为一个值。

# 按 job 聚合,计算每个 job 下所有实例的 CPU 总速率
sum by(job) (rate(node_cpu_seconds_total[5m]))

常用函数详解

rate 与 irate

rate(v range-vector) 计算范围向量中时间序列的每秒平均增长率。适合长区间变化,对突发尖峰有平滑作用。

# 过去 5 分钟 HTTP 请求的每秒速率
rate(http_requests_total[5m])

irate(v range-vector) 使用区间内最后两个样本点计算瞬时增长率,对尖峰敏感,适合做高灵敏度告警。推荐搭配较短的窗口(如 irate(http_requests_total[20s])),但须保证回看窗口内至少有两个点。

increase

increase(v range-vector) 计算窗口内的总增长量,相当于 rate() * 窗口秒数。对计数器类型指标特别有用。

# 过去 1 小时请求增长的总量
increase(http_requests_total[1h])

直方图相关函数

Prometheus 直方图指标自动生成 _bucket_sum_count 后缀的序列。计算分位值使用 histogram_quantile(φ, rate(sum by(le) (histogram_bucket[5m]))) 模式。

# 计算 HTTP 请求持续时间的 99 百分位数
histogram_quantile(0.99, rate(http_request_duration_seconds_bucket[5m]))

务必先用 rate 处理 _bucket 向量,再聚合,最后传入分位函数。

changes 与 resets

  • changes(v range-vector):返回范围内值变化的次数。
  • resets(v range-vector):计数器重置的次数。常用于检测计数器是否在无重启情况下被清零(即可能的 bug)。

predict_linear

predict_linear(v range-vector, t scalar) 基于线性回归预测未来 t 秒后的值,常用于磁盘容量预测。

# 预测 4 小时后磁盘剩余空间
predict_linear(node_filesystem_free_bytes[1h], 4*3600) < 0

其他常用函数

  • absent(v instant-vector):如果向量为空则返回 1,常用于检测指标消失。
  • label_replace(v instant-vector, dst, replacement, src, regex):修改标签。
  • label_join(v instant-vector, dst, sep, src1, src2, ...):合并标签值。

子查询

子查询允许你以不同的解析度对瞬时向量进行范围运算。语法:<expr> [<range>:<resolution>]。 例如,计算过去 30 分钟内 http_requests_total 每秒速率的最大值:

max_over_time(rate(http_requests_total[5m])[30m:1m])

这里内层 rate(…[5m]) 返回一个瞬时向量,但通过子查询以 1 分钟为步长回看 30 分钟,max_over_time 返回最大值。子查询在执行基于滑动窗口的复杂分析时非常强大。

实战场景示例

CPU 使用率百分比

100 - (avg by(instance) (rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100)

该表达式先计算各实例 idle 秒数的平均速率,换算成百分比后,用 100 减去得到使用率。

内存使用率

(1 - node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes) * 100

HTTP 错误率百分比

sum(rate(http_requests_total{status=~"5.."}[5m])) / sum(rate(http_requests_total[5m])) * 100

请求量 Top 5 端点

topk(5, sum by(path) (rate(http_requests_total[5m])))

检测指标缺失的监控

absent(up{job="critical-service"})