17.5.2 向量类型与选择器:瞬时/区间/子查询
PromQL 的结果类型以向量为核心,分为瞬时向量(Instant Vector)与区间向量(Range Vector),并基于选择器(Selector)与子查询构造不同时间维度的数据集。理解它们的评估时刻、采样边界与返回结构,是正确聚合与告警的基础。
1. 向量类型与选择器核心概念#
瞬时向量(Instant Vector)
在某一评估时刻返回一组时间序列及其“最新样本”。典型选择器:
- up{job="node"}
- node_memory_MemAvailable_bytes{instance="10.0.0.1:9100"}
区间向量(Range Vector)
在评估时刻之前的时间窗口内返回样本序列。选择器写法:
- node_cpu_seconds_total{mode!="idle"}[5m]
子查询(Subquery)
对一个表达式产生的瞬时向量再做时间范围采样:
- rate(http_requests_total[5m])[30m:1m]
2. 示例:瞬时/区间/子查询对比#
# 瞬时向量:当前是否存活
up{job="node"}
# 区间向量:过去5分钟CPU非空闲样本序列
node_cpu_seconds_total{mode!="idle"}[5m]
# 区间向量 -> 瞬时向量:5分钟平均CPU使用率
avg by (instance) (
rate(node_cpu_seconds_total{mode!="idle"}[5m])
)
# 子查询:先算5分钟速率,再对30分钟内每分钟采样
rate(http_requests_total[5m])[30m:1m]
命令解释:
- [5m] 是区间窗口,需覆盖至少 2~4 个抓取周期
- [30m:1m] 中 30m 是回溯范围,1m 是评估步长
- rate() 接受区间向量,输出瞬时向量
3. 标签选择器模式与命令说明#
# 精确匹配:性能最好
node_filesystem_avail_bytes{fstype="ext4",mountpoint="/"}
# 正则匹配:成本高,谨慎使用
http_requests_total{job=~"api|web",env!="test"}
# 否定匹配:剔除某类标签
up{job!="blackbox"}
命令解释:
- = 等值匹配
- =~ 正则匹配
- != / !~ 否定匹配
- 正则会增大 CPU 和内存成本
4. 查询验证与命令行工具(含安装)#
使用 promtool 验证 PromQL 语法与表达式:
安装与验证:
# 下载 promtool(以 Linux amd64 为例)
wget https://github.com/prometheus/prometheus/releases/download/v2.49.0/prometheus-2.49.0.linux-amd64.tar.gz
tar -xf prometheus-2.49.0.linux-amd64.tar.gz
cd prometheus-2.49.0.linux-amd64
# 验证表达式
./promtool query instant http://127.0.0.1:9090 'up{job="node"}'
预期效果:
- 返回向量结果或空集
- 若语法错误,promtool 会提示行列位置
5. 排错清单(常见“无数据”与 NaN)#
-
抓取间隔与窗口不匹配
- 抓取间隔 30s,但使用[1m]可能仅 2 个点
- 建议窗口 >=2 * scrape_interval -
指标名称或标签错误
- 用label_values在 Grafana/Prometheus UI 中验证 -
子查询步长过小导致超时
- 将[30m:1s]调整为[30m:1m] -
区间向量直接算术计算
- 先用rate()或_over_time转换为瞬时向量
6. 练习(含预期目标)#
-
练习 1:判断节点是否离线
- 目标:返回up{job="node"} == 0的实例
- 答案示例:
promql up{job="node"} == 0 -
练习 2:计算过去 10 分钟平均 CPU 使用率
- 目标:按实例输出平均 CPU 使用率
promql avg by (instance) ( rate(node_cpu_seconds_total{mode!="idle"}[5m]) ) -
练习 3:对 HTTP QPS 做 1 小时趋势平滑
- 目标:先算 QPS,再做 1 小时区间平均
promql avg_over_time(rate(http_requests_total[5m])[1h:1m])
7. 实战建议#
- 告警优先使用瞬时向量与平滑函数(
avg_over_time),避免抖动 - 趋势分析使用区间向量并控制窗口长度
- 子查询适合多级平滑,但避免在高基数指标上频繁使用
- 稀疏采样指标优先使用
_over_time族函数而非rate()