4. PromQL 基础语法:即时向量与范围向量、选择器与偏移量
PromQL(Prometheus Query Language)是 Prometheus 内置的数据查询语言,用于对时序数据进行实时聚合与分析。理解其核心概念——即时向量、范围向量、选择器以及偏移量——是编写精准查询的基础。本章将逐一拆解这些语法要素,并通过对比表格与流程图帮助建立直观认知。
4.1 即时向量与范围向量
PromQL 查询返回的数据类型分为两种:即时向量(Instant Vector)和范围向量(Range Vector)。两者的核心区别在于:时间维度上的采样点数量。
| 特性 | 即时向量 | 范围向量 |
|---|---|---|
| 定义 | 每个时间序列在当前时刻的一个最新样本值 | 每个时间序列在过去一段时间窗口内的一组样本值 |
| 语法示例 | http_requests_total |
http_requests_total[5m] |
| 返回结构 | 一组标签 + 一个浮点值 | 一组标签 + 一个时间戳-值对数组 |
| 典型用途 | 当前状态、告警规则、瞬时聚合 | 速率计算(rate/irate)、趋势分析、分位数 |
| 是否可直接用于聚合 | 是(如 sum()、avg()) |
否,需先通过函数转换为即时向量 |
关键理解: 即时向量是“快照”,范围向量是“片段”。在误差预算计算中,
rate() 函数必须接收范围向量作为输入,才能计算每秒增长率。
4.2 选择器:精确匹配与正则过滤
选择器用于从指标中筛选出特定的时间序列。PromQL 支持四种标签匹配操作符,覆盖从精确匹配到正则排除的全部场景。
| 操作符 | 含义 | 示例 | 说明 |
|---|---|---|---|
= |
精确相等 | job="api-server" |
标签值必须完全匹配 |
!= |
精确不相等 | job!="api-server" |
排除指定标签值 |
=~ |
正则匹配 | job=~"api-.*" |
标签值匹配正则表达式 |
!~ |
正则排除 | job!~"api-.*" |
标签值不匹配正则表达式 |
实战建议: 在误差预算查询中,常用
=~ 批量选择一组微服务(如 service=~"user-.*"),用 != 排除健康检查端点(如 path!="/healthz")。
4.3 偏移量(offset)
offset 修饰符允许查询过去某个时间点的数据,而非当前时间。其语法为在查询表达式后追加 offset <duration>。
- 基本用法:
http_requests_total{job="api"} offset 1h—— 返回 1 小时前的数据。 - 与范围向量结合:
rate(http_requests_total[5m] offset 1h)—— 计算 1 小时前那 5 分钟窗口内的速率。 - 负偏移(Prometheus 2.28+):
http_requests_total offset -5m—— 查询未来 5 分钟的数据(仅用于特殊场景,如预测)。
注意:
offset 不会改变时间窗口的长度,只改变窗口的起始位置。在误差预算对比(如本周 vs 上周)中,offset 7d 是标准用法。
4.4 综合示例:误差预算中的选择器与偏移量
假设我们有一个 SLO 指标 http_request_duration_seconds_bucket,需要计算过去 7 天的错误预算消耗率,并与上周同期对比:
# 当前周的错误率(过去 7 天)
rate(http_request_duration_seconds_count{job="api", le="+Inf"}[7d])
# 上周同期的错误率(偏移 7 天)
rate(http_request_duration_seconds_count{job="api", le="+Inf"}[7d] offset 7d)
# 排除特定路径的精确错误率
rate(http_request_duration_seconds_count{job="api", path!~"/healthz|/metrics", le="+Inf"}[5m])
4.5 即时向量 vs 范围向量:选择决策流程
下面的 SVG 流程图展示了在编写 PromQL 时,如何根据查询目标选择正确的向量类型。
4.6 选择器与偏移量组合:时间旅行查询
下面的 SVG 图展示了 offset 如何与选择器协同工作,实现“时间旅行”式的对比查询。
4.7 常见错误与避坑指南
- 错误: 对即时向量使用
rate()——rate(http_requests_total)会报错,必须改为rate(http_requests_total[5m])。 - 错误: 范围向量窗口过大导致性能问题 —— 在误差预算查询中,
[30d]可能返回数百万个样本,建议使用[7d]或[1h]配合offset。 - 错误: 正则选择器未锚定 ——
job=~"api"会匹配任何包含 "api" 的字符串(如 "my-api-v2"),应使用job=~"^api$"或job="api"进行精确匹配。 - 错误: 偏移量用于聚合函数内部 ——
sum(rate(http_requests_total[5m])) offset 1h是合法的,但sum(rate(http_requests_total[5m] offset 1h))语义不同,需根据需求选择。
最佳实践: 在编写误差预算 PromQL 时,始终先确定需要的是“当前值”还是“窗口速率”,再选择向量类型。使用
offset 进行同比对比时,确保偏移量与窗口长度匹配业务周期(如 7 天、24 小时)。