PromQL语法
PromQL 语法知识
最后更新时间:2026年1月7日
适用对象:Prometheus 初学者、运维工程师、SRE、DevOps 工程师
目标:系统掌握 PromQL 核心语法、数据模型、函数、操作符及最佳实践
目录
- 一、PromQL 简介
- 二、Prometheus 数据模型
- 三、PromQL 四种数据类型
- 四、时间序列选择器
- 五、标签匹配器(Label Matchers)
- 六、PromQL 操作符
- 七、核心内置函数
- 八、聚合操作(Aggregation Operators)
- 九、高级技巧
- 十、指标类型与函数匹配
- 十一、经典场景示例
- 十二、避坑指南与最佳实践
- 十三、官方资源推荐
一、PromQL 简介
PromQL(Prometheus Query Language)是 Prometheus 内置的函数式查询语言,用于:
- 实时筛选和聚合时间序列数据
- 构建监控图表(Grafana)
- 定义告警规则(Alertmanager)
- 分析系统性能瓶颈
✅ 一句话理解:
PromQL = 从「带标签的时间序列」中筛选、计算、聚合数据的语言
查询流程
graph LR
A[输入查询] --> B[语法解析]
B --> C[标签匹配器筛选时间序列]
C --> D[执行函数/聚合/计算]
D --> E[返回结果]
PromQL ≠ SQL
| 对比项 | SQL | PromQL |
|---|---|---|
| 操作对象 | 表、行 | 时间序列(指标 + 标签) |
| 核心维度 | 行 | 时间 + 标签 |
| 查询结果 | 静态结果集 | 随时间变化的向量 |
| 数据模型 | 关系型 | 多维时间序列 |
二、Prometheus 数据模型
每条时间序列由以下三部分唯一标识:
<metric_name>{<label_name>=<label_value>, ...} @timestamp → value
示例
http_requests_total{method="POST", handler="/api", status="200", instance="10.0.0.91:9100"} 1625097600 → 1500
↑ ↑ ↑ ↑ ↑ ↑ ↑
指标名称 标签名 标签值 标签名 标签值 时间戳 值
- 指标名(Metric Name):如
node_cpu_seconds_total - 标签(Labels):键值对,用于多维切片(如
job,instance,status) - 样本(Sample):
(timestamp, value)数据点
💡 本质:PromQL 是对一堆带标签的时间序列做过滤、计算、聚合。
三、PromQL 四种数据类型
| 类型 | 说明 | 示例 | 特点 |
|---|---|---|---|
| 瞬时向量(Instant Vector) | 某一时刻的多个时间序列 | node_cpu_seconds_total |
多条序列 + 单值(最新值) |
| 区间向量(Range Vector) | 一段时间内的多个时间序列 | node_cpu_seconds_total[5m] |
多条序列 + 多值(历史窗口) |
| 标量(Scalar) | 单一数值 | 3.14 |
无时间戳,可参与计算 |
| 字符串(String) | 字符串字面量 | "hello" |
仅用于标签,几乎不用 |
✅ 重要:写 PromQL 前,必须清楚当前表达式返回的是什么类型!
四、时间序列选择器
4.1 瞬时向量选择器
返回当前时间点的最新样本值。
基本语法
metric_name{label_key="value", ...}
示例
# 所有 http_requests_total 指标
http_requests_total
# 过滤 job="api-server"
http_requests_total{job="api-server"}
# 多标签精确匹配
http_requests_total{method="GET", status="200"}
# 排除特定值
http_requests_total{method!="GET"}
# 正则匹配(支持 RE2 语法)
node_cpu_seconds_total{instance=~"prod-.*"}
http_requests_total{version=~"v1\\..*"}
# 排除正则匹配
http_requests_total{env!~"test|dev"}
# 查找空标签
http_requests_total{instance=""}
# 转义特殊字符(如 .)
{host=~"web\\d+\\.example\\.com"}
4.2 区间向量选择器
返回过去一段时间内的所有样本值,必须配合函数使用。
语法
metric_name[<duration>]
时间单位
| 单位 | 含义 |
|---|---|
ms |
毫秒 |
s |
秒 |
m |
分钟 |
h |
小时 |
d |
天 |
w |
周 |
y |
年 |
⚠️ 注意:
- 必须使用整数(如
5m,不能1.5h)- 可组合(如
1h30m),但顺序必须从大到小
示例
# 过去 5 分钟所有样本
http_requests_total[5m]
# 过去 1 小时请求耗时
http_request_duration_seconds[1h]
# ❌ 错误:区间向量不能直接显示
http_requests_total[5m] # 无效!
# ✅ 正确:必须搭配函数
rate(http_requests_total[5m])
4.3 偏移修饰符(offset)
调整查询的基准时间点,用于对比历史数据。
语法
<selector> offset <duration>
示例
# 查询 1 天前的当前值
http_requests_total offset 1d
# 查询 1 小时前的 5 分钟速率
rate(http_requests_total[5m] offset 1h)
# 对比今日 vs 昨日流量
rate(http_requests_total[1h]) / rate(http_requests_total[1h] offset 1d)
五、标签匹配器(Label Matchers)
用于在选择器中过滤时间序列。
| 操作符 | 含义 | 示例 |
|---|---|---|
= |
精确匹配 | {job="api"} |
!= |
不等于 | {status!="500"} |
=~ |
正则匹配 | {instance=~"prod-.*"} |
!~ |
正则不匹配 | `{env!~"test |
🔍 正则引擎:基于 RE2,不支持向前断言(lookahead)等高级特性。
六、PromQL 操作符
6.1 算术操作符
| 操作符 | 说明 |
|---|---|
+ - * / % ^ |
加减乘除、取模、幂运算 |
示例
# 计算错误率
rate(http_requests_total{status="500"}[5m]) / rate(http_requests_total[5m])
# 内存使用百分比
(node_memory_MemTotal_bytes - node_memory_MemFree_bytes) / node_memory_MemTotal_bytes * 100
# 转换为比特率
rate(node_network_receive_bytes_total[2m]) * 8
6.2 比较操作符
| 操作符 | 说明 |
|---|---|
== != |
等于、不等于 |
> < >= <= |
大于、小于等 |
== bool != bool |
返回布尔值(0 或 1) |
示例
# 返回值 > 100 的时间序列
node_filesystem_avail_bytes > 100
# 返回布尔结果(用于过滤)
node_filesystem_avail_bytes > bool 100
# 筛选内存不足 100MB 的节点
node_memory_free_bytes < 100 * 1024^2
6.3 逻辑/集合操作符
| 操作符 | 说明 |
|---|---|
and |
交集(保留两边都存在的序列) |
or |
并集(合并序列) |
unless |
差集(左边存在但右边不存在) |
示例
# 保留 job="api" 且 status="500" 的序列
http_requests_total{job="api"} and http_requests_total{status="500"}
# 合并两个指标
http_requests_total{job="api"} or http_requests_total{job="frontend"}
# 排除特定实例
http_requests_total unless http_requests_total{instance="backup"}
6.4 操作符优先级(从高到低)
^
*, /, %
+, -
==, !=, <=, <, >=, >
and, unless
or
💡 建议使用括号
()明确优先级,避免歧义。
七、核心内置函数
7.1 速率与增量函数(Counter 专用)
| 函数 | 用途 | 示例 |
|---|---|---|
rate(v range) |
计算每秒平均增长率(平滑) | rate(http_requests_total[5m]) |
irate(v range) |
计算瞬时增长率(敏感) | irate(http_requests_total[5m]) |
increase(v range) |
计算总增量 | increase(http_requests_total[1h]) |
📌 生产建议:
- 告警用
rate()(平滑,抗抖动)- 瞬时监控用
irate()(检测峰值)- 区间至少是抓取间隔的 4 倍(如 scrape_interval=15s → range ≥ 1m)
7.2 变化量函数(Gauge 专用)
| 函数 | 用途 | 示例 |
|---|---|---|
delta(v range) |
绝对变化量(首尾差值) | delta(memory_usage_bytes[5m]) |
idelta(v range) |
最后两个点的差值 | idelta(cpu_temp[1m]) |
应用场景
# 内存是否持续上涨
delta(container_memory_usage_bytes[10m]) > 0
# 队列积压变化
delta(queue_length[5m]) # 正数:积压增加;负数:消费更快
7.3 时间窗口聚合函数(_over_time)
对区间向量进行统计。
| 函数 | 说明 |
|---|---|
avg_over_time(v) |
平均值 |
min_over_time(v) |
最小值 |
max_over_time(v) |
最大值 |
sum_over_time(v) |
总和 |
count_over_time(v) |
样本数 |
quantile_over_time(φ, v) |
分位数 |
示例
# 过去 1 小时内存可用量的平均值
avg_over_time(node_memory_free_bytes[1h])
# 过去 30 分钟磁盘 IO 最大值
max_over_time(disk_io_ops[30m])
7.4 预测与趋势函数
| 函数 | 用途 | 示例 |
|---|---|---|
predict_linear(v, s) |
线性预测未来值 | predict_linear(node_filesystem_free_bytes[1h], 6*3600) < 0 |
✅ 用于磁盘、内存等资源耗尽预警。
7.5 聚合与排序函数
| 函数 | 说明 |
|---|---|
sum(v) |
求和 |
avg(v) |
平均值 |
min(v)/max(v) |
最小/最大值 |
count(v) |
计数 |
topk(k, v) |
前 k 个最大值 |
bottomk(k, v) |
前 k 个最小值 |
sort(v) |
升序排序 |
sort_desc(v) |
降序排序 |
八、聚合操作(Aggregation Operators)
8.1 聚合函数列表
sum:求和min:最小值max:最大值avg:平均值stddev:标准差stdvar:方差count:元素个数count_values:等于某值的元素个数bottomk:最小的 k 个元素topk:最大的 k 个元素quantile:分位数
8.2 by 与 without 子句
| 子句 | 作用 |
|---|---|
by (label1, label2) |
仅保留指定标签进行聚合 |
without (label1) |
移除指定标签后聚合 |
语法格式(两种等价写法)
<agg>(vector) by (labels)
<agg> by (labels) (vector)
8.3 实战示例
# 按 job 聚合请求总数
sum by (job) (rate(http_requests_total[5m]))
# 排除 instance 标签后取最大值
max without(instance) (cpu_usage)
# 统计不同状态码的数量
count by(status_code) (http_requests_total)
# 获取每个 job 中 CPU 使用最高的实例
topk by(job) (1, rate(container_cpu_usage_seconds_total[1m]))
九、高级技巧
9.1 子查询(Subquery)
在时间范围内以固定间隔执行瞬时查询。
语法
<instant_query>[<range>:<resolution>]
示例
# 计算过去 1 小时内每 5 分钟速率的最大值
max_over_time( rate(http_requests_total[5m])[1h:5m] )
⚠️ 注意:子查询性能开销大,慎用!
9.2 条件表达式(布尔过滤)
结合 bool 和逻辑操作符实现复杂过滤。
# 错误率 > 5% 且总请求 > 100
(
sum(rate(http_requests_total{status=~"5.."}[5m]))
/
sum(rate(http_requests_total[5m]))
) > bool 0.05
and
sum(rate(http_requests_total[5m])) > 100
十、指标类型与函数匹配
10.1 Counter(计数器)
- 特性:只增不减(重启归零)
- 适用函数:
rate(),irate(),increase() - 典型指标:
http_requests_total,node_cpu_seconds_total
10.2 Gauge(仪表盘)
- 特性:可增可减
- 适用函数:
delta(),predict_linear() - 典型指标:
node_memory_MemFree_bytes,node_load1
10.3 Histogram(直方图)
- 生成指标:
xxx_bucket{le="..."}:累积计数xxx_sum:总和xxx_count:总数
- 核心函数:
histogram_quantile(φ, xxx_bucket) - 示例:
# P95 延迟 histogram_quantile(0.95, rate(http_request_duration_seconds_bucket[5m]))
10.4 Summary(摘要)
- 客户端计算分位数,服务端直接抓取
- 不推荐(无法跨实例聚合)
- 优先用 Histogram
十一、经典场景示例
1. CPU 使用率
100 - (
avg by(instance) (
rate(node_cpu_seconds_total{mode="idle"}[5m])
) * 100
)
2. HTTP 错误率
sum(rate(http_requests_total{status=~"5.."}[5m]))
/
sum(rate(http_requests_total[5m]))
3. 内存不足预警
node_filesystem_free_bytes{mountpoint="/"}
/
node_filesystem_size_bytes{mountpoint="/"} < 0.2
4. 磁盘 6 小时后满载预测
predict_linear(node_filesystem_free_bytes[1h], 6*3600) < 0
十二、避坑指南与最佳实践
| 问题 | 解决方案 |
|---|---|
❌ http_requests_total[5m] 无效 |
✅ 必须搭配函数:rate(http_requests_total[5m]) |
| ❌ 全量扫描(无标签过滤) | ✅ 先用标签缩小范围:{cluster="prod"} |
| ❌ Counter 重置导致负值 | ✅ 使用 rate()/increase() 自动处理 |
| ❌ 区间太短(< 2×scrape_interval) | ✅ 至少 4 倍抓取间隔(如 1m for 15s) |
❌ 混淆 rate() 与 irate() |
✅ 告警用 rate(),瞬时监控用 irate() |
| ❌ 在 Summary 上计算分位数 | ✅ 改用 Histogram + histogram_quantile() |
💡 Grafana 提示:在 Explore 模式中实时验证查询,结合 Time Range 和 Step 调整精度。
十三、官方资源推荐
- 官方文档:https://prometheus.io/docs/prometheus/latest/querying/basics/
- PromQL 备忘单:https://prometheus.io/docs/prometheus/latest/querying/examples/
- 函数大全:https://prometheus.io/docs/prometheus/latest/querying/functions/
- Grafana Explore:实时调试 PromQL 的最佳工具
✅ 结语:PromQL 是云原生可观测性的核心技能。掌握其数据模型、函数与聚合机制,你将能从容应对任何监控与告警场景。

浙公网安备 33010602011771号