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 的核心脉络串起来了:
实战组合拳
光讲理论没意思。我给你一个真实场景:
假设你接到告警,说 API 响应变慢了。你会怎么查?
- 先看整体流量:
sum by (job) (rate(http_requests_total[5m]))—— 看看是不是流量突增。 - 再看错误率:
sum by (status) (rate(http_requests_total{status=~"5.."}[5m]))—— 看看是不是 5xx 暴增。 - 最后看资源:
sum by (instance) (rate(node_cpu_seconds_total{mode="user"}[5m]))—— 看看哪台机器 CPU 飙了。
这三步走下来,大部分问题都能定位到根因。
我的经验:别一上来就写复杂的 PromQL。先跑一个简单的,确认数据对,再逐步加条件。我见过太多人写了个 10 行的查询,结果发现标签名都拼错了。
好了,PromQL 的核心概念就这些。即时向量和范围向量是基础,选择器帮你精确锁定目标,rate/irate/increase 各有各的用途,sum by 让数据变得可读。把这些练熟,日常监控排查基本够用了。