即时向量与范围向量:理解 Instant Vector 与 Range Vector 的区别

在 PromQL 中,向量是查询返回的核心数据结构。理解 即时向量(Instant Vector) 与 范围向量(Range Vector) 的区别,是编写精准告警表达式的基础。两者的核心差异在于:是否携带时间窗口内的历史样本数据。

1. 核心概念对比

特性 即时向量 (Instant Vector) 范围向量 (Range Vector)
定义 每个时间序列在单个时间点上的最新样本值 每个时间序列在指定时间窗口内的一组样本值
语法示例 http_requests_total{job="api"} http_requests_total{job="api"}[5m]
返回结构 一组键值对(标签 + 一个浮点数) 一组键值对(标签 + 一个时间序列数组)
典型用途 当前值告警、瞬时状态判断 速率计算、趋势分析、滑动窗口聚合
能否直接用于算术运算 可以,直接与标量或另一即时向量运算 不能,必须先通过聚合函数(如 rate、avg_over_time)转换
关键记忆点: 即时向量是“快照”,范围向量是“录像片段”。告警表达式通常先用范围向量计算趋势,再通过函数转为即时向量进行阈值比较。

2. 向量选择器 {}:精确过滤标签

向量选择器使用花括号 {} 来根据标签(Label)过滤时间序列。它是 PromQL 中最常用的过滤机制。

  • 精确匹配:{job="prometheus"} — 只选择 job 标签为 "prometheus" 的序列。
  • 正则匹配:{job=~"prometheus|node"} — 选择 job 匹配正则的序列。
  • 排除匹配:{job!="cadvisor"} — 排除 job 为 "cadvisor" 的序列。
  • 存在性检查:{__name__=~".*_total"} — 选择所有以 _total 结尾的指标。
最佳实践: 在告警规则中,尽量使用精确的标签选择器缩小查询范围,避免全量扫描,提升 Prometheus 查询性能。

3. 时间范围 [5m]:定义滑动窗口

时间范围选择器紧跟在指标名或向量选择器之后,用方括号 [] 包裹,指定要回溯的时间长度。常见的时间单位包括:

  • s — 秒(如 [30s])
  • m — 分钟(如 [5m])
  • h — 小时(如 [1h])
  • d — 天(如 [1d])

时间窗口的选择直接影响告警的灵敏度与稳定性:

窗口大小 适用场景 告警特点
[1m] 高频抖动检测、快速响应 敏感,易误报
[5m] 通用业务监控、中等频率指标 平衡灵敏度与稳定性
[1h] 慢速趋势、容量规划 稳定,但延迟高

4. 即时向量与范围向量的转换流程

以下 SVG 图展示了从原始指标到告警表达式的典型数据流:

即时向量 vs 范围向量:数据流与转换 原始指标 http_requests_total 即时向量 当前最新值 范围向量 5分钟样本数组 无时间范围 添加 [5m] 聚合函数 rate() / avg_over_time() 必须转换 告警阈值比较 也可直接比较 范围向量不能直接参与 算术运算,需先聚合

5. 实战案例:从范围向量到告警表达式

以下是一个完整的告警表达式编写流程,展示如何从范围向量推导出可用的告警规则:

  1. 原始查询(范围向量):
    http_requests_total{job="api"}[5m]
    返回每个 job="api" 序列在过去 5 分钟内的所有样本。
  2. 计算速率(转为即时向量):
    rate(http_requests_total{job="api"}[5m])
    rate() 函数将范围向量转换为每秒增长率(即时向量)。
  3. 设置告警阈值:
    rate(http_requests_total{job="api"}[5m]) > 100
    当每秒请求数超过 100 时触发告警。
常见错误: 直接对范围向量使用比较运算符,如 http_requests_total[5m] > 100。这会导致语法错误,因为范围向量不是标量或即时向量。必须先通过 rate、avg_over_time 等函数转换。

6. 向量选择器与时间范围组合示例

下表展示了不同组合的查询效果:

查询表达式 向量类型 返回内容
node_cpu_seconds_total 即时向量 所有 CPU 序列的当前最新值
node_cpu_seconds_total{mode="idle"} 即时向量 仅 idle 模式的当前值
node_cpu_seconds_total{mode="idle"}[5m] 范围向量 idle 模式过去 5 分钟的所有样本
avg_over_time(node_cpu_seconds_total{mode="idle"}[5m]) 即时向量 idle 模式过去 5 分钟的平均值

7. 避坑指南:常见误解

  • 误解一:“范围向量比即时向量慢。” — 实际上,范围向量需要读取更多数据,但合理使用索引和标签过滤后,性能差异可接受。
  • 误解二:“[5m] 表示每 5 分钟采样一次。” — 不对,它表示查询过去 5 分钟内的所有样本,采样间隔由 Prometheus 的 scrape_interval 决定。
  • 误解三:“即时向量不能用于趋势分析。” — 即时向量可以配合 offset 关键字实现前后对比,但范围向量更适合滑动窗口计算。
总结: 编写告警表达式时,先用 {} 精确选择目标序列,再用 [时间范围] 定义滑动窗口,最后通过聚合函数转换为即时向量与阈值比较。掌握这一流程,即可避免 90% 的语法错误。