前言
在上一篇文章中,我们学习了 Prometheus 的 Relabeling 机制,掌握了如何对监控目标进行筛选和标签转换。然而,数据采集只是第一步——如何从海量监控数据中快速提取有价值的信息,才是衡量监控系统价值的关键。
PromQL(Prometheus Query Language)正是这把打开数据宝库的钥匙。它是 Prometheus 内置的函数式查询语言,用于实时筛选、聚合和分析时间序列数据。无论是构建 Grafana 监控大屏,还是配置告警规则,都离不开 PromQL。
本文将从零开始,用最通俗的语言和大量实例,带你掌握 PromQL 的核心用法。
一、理解 PromQL 的基本概念
在开始写查询之前,先搞清楚三个核心概念——瞬时向量、区间向量和标量。
1.1 三种数据类型
| 类型 | 含义 | 示例 |
|---|---|---|
| 瞬时向量(Instant Vector) | 一组时间序列,每个序列只有一个最新的采样值 | node_cpu_seconds_total |
| 区间向量(Range Vector) | 一组时间序列,每个序列包含一段时间内的多个采样值 | node_cpu_seconds_total[5m] |
| 标量(Scalar) | 一个单独的浮点数,没有时间戳 | 10、3.14 |
用一句话理解:
瞬时向量就像快照——此时此刻每个指标的值是多少
区间向量就像录像——过去5分钟每个指标的变化过程
标量就是一个数字——没有任何附加信息
1.2 最简单的查询:瞬时向量
最基本的 PromQL 查询就是直接写一个指标名称:
promql
node_cpu_seconds_total这条查询会返回所有node_cpu_seconds_total时间序列的最新值。
加上标签过滤,可以精确筛选:
promql
node_cpu_seconds_total{cpu="0", mode="idle"}这里的{cpu="0", mode="idle"}就是标签过滤器——只返回 cpu 为 0、mode 为 idle 的数据。
支持的比较运算符:
| 运算符 | 含义 |
|---|---|
= | 等于 |
!= | 不等于 |
=~ | 正则匹配 |
!~ | 正则不匹配 |
promql
# 排除 cpu0,只保留 user 和 system 模式 node_cpu_seconds_total{cpu!="0", mode=~"user|system"}二、二元运算符号
PromQL 支持在查询中对数据进行各种运算。
2.1 算术运算符
| 运算符 | 含义 |
|---|---|
+ | 加法 |
- | 减法 |
* | 乘法 |
/ | 除法 |
% | 取模(求余数) |
^ | 幂运算 |
向量与标量运算:将向量中的每一个值与标量进行运算。
promql
# 所有内存值乘以 2 node_memory_MemFree_bytes * 2 # 所有 CPU 使用时间除以 100 node_cpu_seconds_total / 100向量与向量运算:将左边向量的每个元素与右边向量中标签匹配的元素进行运算。
promql
# 计算内存使用率 (node_memory_MemTotal_bytes - node_memory_MemFree_bytes) / node_memory_MemTotal_bytes * 1002.2 比较运算符
| 运算符 | 含义 |
|---|---|
== | 等于 |
!= | 不等于 |
> | 大于 |
< | 小于 |
>= | 大于等于 |
<= | 小于等于 |
比较运算符默认会过滤掉不满足条件的数据:
promql
# 只保留可用内存大于 100MB 的序列 node_memory_MemFree_bytes > 100 * 1024 * 1024如果只想比较而不过滤,加上bool关键字,结果返回 1(真)或 0(假):
promql
node_memory_MemFree_bytes > bool 100 * 1024 * 10242.3 逻辑/集合运算符
| 运算符 | 含义 |
|---|---|
and | 交集——同时存在于左右两边 |
or | 并集——存在于左边或右边 |
unless | 差集——存在于左边但不在右边 |
promql
# 只保留 up=1 的主机 up == 1 and node_cpu_seconds_total # 合并两个查询结果 up{job="prometheus"} or up{job="node"}三、聚合操作
聚合函数的作用是将多个时间序列合并成一个或几个。它们只能用于瞬时向量。
3.1 常用聚合函数
| 函数 | 含义 |
|---|---|
sum() | 求和 |
min() | 最小值 |
max() | 最大值 |
avg() | 平均值 |
count() | 计数 |
stddev() | 标准差 |
topk(k, v) | 前 k 个最大值 |
bottomk(k, v) | 后 k 个最小值 |
quantile(φ, v) | 分位数(φ 在 0~1 之间) |
3.2 基础用法
promql
# 所有服务器的 CPU 空闲时间总和 sum(node_cpu_seconds_total{mode="idle"}) # 所有服务器的最大可用内存 max(node_memory_MemFree_bytes) # 所有服务器的平均内存使用率 avg((node_memory_MemTotal_bytes - node_memory_MemFree_bytes) / node_memory_MemTotal_bytes)3.3 分组聚合:by 和 without
聚合时如果不分组,所有数据会合并成一个结果。使用by或without可以按维度分组。
by (label):只保留指定标签,按这些标签分组。
promql
# 按实例分组,计算每个实例的 CPU 空闲时间总和 sum(node_cpu_seconds_total{mode="idle"}) by (instance) without (label) :移除指定标签,用剩余的标签分组。 promql # 移除 cpu 标签,用其他标签分组 sum(node_cpu_seconds_total{mode="idle"}) without (cpu)实战示例:
promql
# 每个服务的 QPS(按 job 分组) sum(rate(http_requests_total[5m])) by (job) # 每个实例的 CPU 使用率 100 - (avg(rate(node_cpu_seconds_total{mode="idle"}[5m])) by (instance) * 100)四、瞬时向量匹配
当两个向量进行运算时,PromQL 需要决定哪个元素和哪个元素配对。这就涉及向量匹配(Vector Matching)。
4.1 一对一匹配(默认)
默认情况下,PromQL 会找标签完全一致的元素进行配对。
promql
node_memory_MemFree_bytes + node_memory_Cached_bytes只有当两个指标的标签完全相同时,才会相加。如果标签不完全一致,数据就会被丢弃。
4.2 使用on和ignoring指定匹配标签
on(label):只使用指定的标签进行匹配。
promql
# 只在 instance 和 job 标签匹配时相加 node_memory_MemFree_bytes + on(instance, job) node_memory_Cached_bytesignoring(label):忽略指定的标签,用剩余标签匹配。
promql
# 忽略 instance 和 job 标签进行匹配 node_memory_MemFree_bytes + ignoring(instance, job) node_memory_Cached_bytes4.3 多对一/一对多匹配:group_left和group_right
当左边一个元素匹配右边多个元素(或反过来)时,需要使用group_left或group_right明确匹配关系。
promql
# 每个实例的 CPU 使用率除以该实例的 CPU 核心数 rate(node_cpu_seconds_total[5m]) / on(instance, job) group_left(node) node_cpu_countgroup_left表示右边的多个元素匹配左边的一个元素,结果保留左边的所有标签。
五、常用内置函数
PromQL 提供了大量内置函数,下面介绍最常用的几个。
5.1 速率计算函数(Counter 专用)
Counter 类型指标只增不减,直接用值没有意义,需要用函数计算变化速率。
| 函数 | 含义 | 适用场景 |
|---|---|---|
rate(v[5m]) | 区间内的平均每秒增长率 | QPS、流量趋势(平滑稳定) |
irate(v[5m]) | 区间内最后两个点的瞬时增长率 | 突发流量检测(更灵敏) |
increase(v[1h]) | 区间内的总增长量 | 统计一段时间内的总请求数 |
promql
# 过去5分钟的平均 QPS rate(http_requests_total[5m]) # 捕捉瞬时突发流量 irate(http_requests_total[5m]) # 过去1小时的 500 错误总数 increase(http_requests_total{status="500"}[1h])5.2 变化检测函数(Gauge 专用)
| 函数 | 含义 |
|---|---|
delta(v[10m]) | 区间内起始值到结束值的变化量 |
idelta(v[1m]) | 区间内最后两个点的变化量 |
promql
# 过去10分钟内存变化量 delta(node_memory_MemFree_bytes[10m]) # 最近一分钟网络流量变化 idelta(node_network_receive_bytes_total[1m])5.3 数学函数
| 函数 | 含义 |
|---|---|
abs(v) | 绝对值 |
ceil(v) | 向上取整 |
floor(v) | 向下取整 |
round(v) | 四舍五入 |
sqrt(v) | 平方根 |
promql
# 磁盘已用空间(绝对值) abs(node_filesystem_avail_bytes - node_filesystem_size_bytes) # 内存使用量(MB,向下取整) floor(node_memory_MemFree_bytes / 1024 / 1024)5.4 分位数函数
histogram_quantile(φ, v)用于从 Histogram 类型指标计算分位数:
promql
# 过去5分钟 API 请求的 95 分位延迟 histogram_quantile(0.95, sum(rate(api_request_duration_seconds_bucket[5m])) by (le))5.5 标签处理函数
| 函数 | 含义 |
|---|---|
label_join(v, dst, sep, src...) | 将多个标签值合并成一个新标签 |
label_replace(v, dst, regex, src) | 用正则从源标签提取内容到目标标签 |
promql
# 将 instance 和 job 合并为 service 标签 label_join(http_requests_total, "service", "-", "job", "instance") # 从 instance="192.168.1.1:9100" 提取 IP 到 host 标签 label_replace(node_cpu_seconds_total, "host", "$1", "instance", "(.*):.*")六、结合 Grafana 可视化
学习了 PromQL,最终还是要落到可视化上。Grafana 是 Prometheus 最常用的可视化搭档。
6.1 在 Grafana 中使用 PromQL
第一步:确保 Grafana 已添加 Prometheus 数据源。
第二步:创建 Dashboard → 添加 Panel → 在查询编辑器中输入 PromQL。
第三步:选择图表类型(Time series、Stat、Table 等)。
Grafana 的查询编辑器支持两种模式:
Builder 模式:通过下拉菜单选择指标和标签,适合初学者
Code 模式:直接编写 PromQL,支持自动补全和高亮
6.2 常用可视化场景与 PromQL
| 可视化需求 | PromQL 示例 |
|---|---|
| CPU 使用率 | 100 - (avg(rate(node_cpu_seconds_total{mode="idle"}[5m])) by (instance) * 100) |
| 内存使用率 | (1 - node_memory_MemFree_bytes / node_memory_MemTotal_bytes) * 100 |
| QPS 趋势 | sum(rate(http_requests_total[5m])) by (job) |
| 服务可用性 | avg(up) by (job) * 100 |
| TOP 5 请求量 | topk(5, sum(rate(http_requests_total[5m])) by (endpoint)) |
| 错误率 | sum(rate(http_requests_total{status=~"5.."}[5m])) / sum(rate(http_requests_total[5m])) |
6.3 Grafana 面板配置小技巧
变量使用:在 Dashboard 设置中定义变量(如
$instance、$job),查询时动态替换:promql
node_cpu_seconds_total{instance="$instance"}Legend 格式化:用
{{标签名}}让图例更清晰:text
{{instance}} - {{mode}}告警配置:在 Panel 的 Alert 选项卡中,基于 PromQL 配置告警阈值
七、总结
本文系统介绍了 PromQL 的核心知识体系:
| 模块 | 核心要点 |
|---|---|
| 基本概念 | 瞬时向量(快照)、区间向量(录像)、标量(数字) |
| 二元运算符 | 算术(+-*/)、比较(><==)、逻辑(andor) |
| 聚合操作 | sum、avg、max、topk等,配合by/without分组 |
| 向量匹配 | 默认一对一匹配,用on/ignoring指定匹配标签 |
| 内置函数 | rate(速率)、increase(增量)、histogram_quantile(分位数)等 |
| Grafana 集成 | 查询编辑器输入 PromQL,选择图表类型即可可视化 |
学习建议:
先学会看:在 Prometheus UI(
http://<IP>:9090/graph)中尝试简单查询多用
rate:Counter 类型指标一定要用rate或increase才有意义注意分组:聚合时想想需不需要
by,否则所有数据会合并成一个值善用 Grafana:在 Grafana 中边写查询边看图表,学习效率最高
一句话总结:PromQL 是 Prometheus 监控体系的核心语言——掌握了它,你就能从海量监控数据中任意提取、聚合和分析,让数据真正为你所用。