PromQL 查询 Prometheus 指标的常用语法
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:左边存在但右边不存在的标签组合
这些操作符常用于告警规则或复杂过滤,遵循向量匹配规则。
聚合操作
聚合将多条时间序列压缩为一条或多条。常用聚合函数:
sum、min、max、avg、stddev、counttopk(k, expr):前 k 个最大值bottomk(k, expr):后 k 个最小值quantile(φ, expr):φ 分位数
必须配合 by 或 without 指定聚合的维度,否则可能将所有实例合并为一个值。
# 按 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"})