PromQL 入门:即时向量与范围向量、选择器与标签匹配、常用函数

PromQL 是 Prometheus 的查询语言。说白了,它就是你和监控数据对话的方式。我刚接触时觉得它语法有点怪,但用顺手了就会发现——它其实很符合运维的直觉。

这一节,我带你从最核心的两个概念开始:即时向量和范围向量。搞懂它们,后面的函数和聚合就顺了。

即时向量 vs 范围向量

这两个概念,我当年花了整整一下午才彻底搞明白。其实没那么复杂。

  • 即时向量(Instant Vector):查某个时间点的一组数据。比如“现在这一刻,所有机器的 CPU 使用率”。
  • 范围向量(Range Vector):查某段时间窗口内的一组数据。比如“过去 5 分钟,每台机器的 CPU 使用率变化”。

你想想看,如果只查一个时间点,你只能看到瞬时值。但瓶颈定位往往需要看趋势——这时候就必须用范围向量。

核心区别一句话:即时向量 = 快照;范围向量 = 录像。

看个例子:

# 即时向量:当前 CPU 使用率
node_cpu_seconds_total{mode="idle"}

# 范围向量:过去 5 分钟的 CPU 使用率
node_cpu_seconds_total{mode="idle"}[5m]

注意那个 [5m]。它就是范围向量的标志。我习惯把它读作“往前看 5 分钟”。

选择器与标签匹配

Prometheus 的数据都是带标签的。标签就是维度。你想精确锁定某台机器、某个服务,就得靠标签选择器。

常用的匹配操作符有四种:

操作符 含义 示例
= 精确匹配 job="api-server"
!= 不等于 job!="api-server"
=~ 正则匹配 instance=~"web-.*"
!~ 正则排除 instance!~"canary-.*"

我的习惯:能用 = 就别用正则。正则虽然灵活,但性能开销大。我曾经在生产环境用了一个宽泛的正则,直接把 Prometheus 查询打挂了——嗯,那次之后我就老实了。

组合使用也很常见:

# 查 api-server 这个 job 下,所有非 canary 实例的 CPU 使用率
node_cpu_seconds_total{job="api-server", instance!~"canary-.*"}

常用函数:rate / irate / increase

这三个函数,是 PromQL 里最常用的。我几乎每天都会用到它们。

rate()

rate() 计算的是每秒平均增长率。它基于范围向量,算的是整个时间窗口内的平均速率。

# 过去 5 分钟,每秒平均请求数
rate(http_requests_total[5m])

它适合看平稳趋势。比如你想知道“这 5 分钟流量是不是涨了”,用 rate 就很稳。

irate()

irate() 计算的是瞬时增长率。它只看区间内最后两个数据点,反应更快。

# 瞬时请求速率(更敏感)
irate(http_requests_total[5m])

它适合捕捉突刺。比如你想看“刚才那一下 spike 到底有多猛”,irate 更合适。

避坑指南:我曾经在告警规则里用了 irate,结果因为数据点间隔不均匀,告警频繁抖动。后来改回 rate,问题就解决了。我的建议是——告警用 rate,排查用 irate。

increase()

increase() 算的是时间窗口内的增量。比如“过去 5 分钟总共增加了多少请求”。

# 过去 5 分钟,请求总数增量
increase(http_requests_total[5m])

它适合容量规划。比如你想知道“这 5 分钟比上 5 分钟多了多少流量”,increase 最直观。

聚合操作:sum by

数据查出来了,但往往维度太多。你需要聚合。

sum by 是最常用的聚合方式。它按指定标签分组求和。

# 按 job 分组,求每个 job 的 CPU 使用率
sum by (job) (rate(node_cpu_seconds_total{mode="idle"}[5m]))

这个查询的意思是:先算每台机器的 CPU 空闲率,然后按 job 分组求和。结果就是每个 job 的总空闲率。

我经常用这个来快速定位“哪个服务最吃资源”。

知识体系总览

下面这张图,把 PromQL 的核心脉络串起来了:

PromQL 核心知识体系 PromQL 查询 即时向量 范围向量 标签选择器:= != =~ !~ rate() 平均速率 irate() 瞬时速率 increase() 增量 sum by (job) 分组聚合 告警用 rate 排查用 irate 规划用 increase

实战组合拳

光讲理论没意思。我给你一个真实场景:

假设你接到告警,说 API 响应变慢了。你会怎么查?

  1. 先看整体流量:sum by (job) (rate(http_requests_total[5m])) —— 看看是不是流量突增。
  2. 再看错误率:sum by (status) (rate(http_requests_total{status=~"5.."}[5m])) —— 看看是不是 5xx 暴增。
  3. 最后看资源:sum by (instance) (rate(node_cpu_seconds_total{mode="user"}[5m])) —— 看看哪台机器 CPU 飙了。

这三步走下来,大部分问题都能定位到根因。

我的经验:别一上来就写复杂的 PromQL。先跑一个简单的,确认数据对,再逐步加条件。我见过太多人写了个 10 行的查询,结果发现标签名都拼错了。

好了,PromQL 的核心概念就这些。即时向量和范围向量是基础,选择器帮你精确锁定目标,rate/irate/increase 各有各的用途,sum by 让数据变得可读。把这些练熟,日常监控排查基本够用了。