4. PromQL 入门:即时向量与范围向量、选择器、操作符、聚合操作

PromQL(Prometheus Query Language)是 Prometheus 生态的核心查询语言,用于实时分析和聚合时间序列数据。在云原生资源配额与瓶颈诊断场景中,90% 以上的诊断表达式都基于本章的四个基础概念:向量类型、选择器、操作符和聚合操作。掌握这些概念,是编写精准告警规则和容量分析查询的前提。

4.1 即时向量与范围向量

PromQL 的查询结果分为两种向量类型,理解它们的区别是正确使用函数和聚合的基础。

向量类型 定义 典型场景 示例
即时向量 (Instant Vector) 每个时间序列在当前查询时刻只有一个最新样本值 实时告警、当前资源使用率、仪表盘瞬时面板 node_memory_MemTotal_bytes
范围向量 (Range Vector) 每个时间序列包含一段时间窗口内的一组有序样本 速率计算、趋势分析、历史百分位、瓶颈持续时间判断 node_memory_MemTotal_bytes[5m]
关键区分: 范围向量必须用 [时间窗口] 后缀标识,例如 [5m]、[1h]。大多数聚合函数(如 rate、avg_over_time)只接受范围向量作为输入参数。

下面的 SVG 图展示了即时向量与范围向量在时间轴上的数据采样差异:

即时向量 vs 范围向量 数据采样对比 时间轴 t₀ tₙ 即时向量 当前时刻 最新值 范围向量 时间窗口 [5m] 样本序列(有序、带时间戳)

4.2 选择器:精确锁定目标时间序列

选择器用于从 Prometheus 存储中筛选出特定的时间序列。最常用的是标签匹配器,支持四种匹配模式:

匹配器 语法 含义 示例
精确相等 = 标签值完全等于指定字符串 node_cpu_seconds_total{instance="10.0.0.1:9100"}
不等 != 标签值不等于指定字符串 node_cpu_seconds_total{instance!="10.0.0.1:9100"}
正则匹配 =~ 标签值匹配正则表达式 node_cpu_seconds_total{instance=~"10.0.0.*:9100"}
正则排除 !~ 标签值不匹配正则表达式 node_cpu_seconds_total{instance!~"10.0.0.*:9100"}
实战技巧: 在 Kubernetes 环境中,经常使用 {namespace="kube-system"} 或 {pod=~".*api.*"} 来缩小查询范围。空标签选择器 {} 表示匹配所有序列,但性能较差,应尽量避免。

4.3 操作符:算术、比较与逻辑

PromQL 支持三类操作符,用于对向量或标量进行运算:

4.3.1 算术操作符

支持 +、-、*、/、%、^。例如计算 CPU 使用率:

100 * (1 - avg(rate(node_cpu_seconds_total{mode="idle"}[5m])) by (instance))

4.3.2 比较操作符

支持 ==、!=、>、<、>=、<=。比较操作符常用于告警规则,返回布尔值(0 或 1):

node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes < 0.1

4.3.3 逻辑/集合操作符

支持 and、or、unless,用于合并多个查询结果:

node_load1 > 5 or node_load5 > 3
注意: 算术和比较操作符在应用于两个向量时,默认使用一对一匹配。如果标签集合不一致,需要使用 on、ignoring、group_left、group_right 进行向量匹配控制,这在多维度资源配额计算中非常关键。

4.4 聚合操作:从多维到一维的降维分析

聚合操作将多个时间序列合并为一个或一组结果,是资源配额汇总和瓶颈排名的核心工具。最常用的聚合函数包括:

聚合函数 作用 典型场景
sum 对所有序列的值求和 计算集群总 CPU 核数、总内存量
avg 计算所有序列的平均值 集群平均 CPU 使用率、平均延迟
min / max 取最小值 / 最大值 找出最空闲 / 最繁忙的节点
count 统计序列数量 统计运行中的 Pod 数量
topk / bottomk 返回前 K 个 / 后 K 个最大值 找出 CPU 使用率最高的 Top 5 Pod
quantile 计算分位数(0-1) P99 延迟、P95 资源使用量

聚合操作通常配合 by 或 without 子句进行维度控制:

# 按 namespace 聚合 CPU 使用量(单位:核)
sum(rate(container_cpu_usage_seconds_total[5m])) by (namespace)

# 按 node 聚合,排除 cpu 标签维度
sum(rate(node_cpu_seconds_total{mode!="idle"}[5m])) without (cpu, mode)

# 找出内存使用量最高的 Top 5 Pod
topk(5, container_memory_usage_bytes)

下面的 SVG 图展示了从原始指标到聚合结果的完整数据流:

PromQL 聚合操作数据流 原始指标 node_cpu_seconds_total 选择器过滤 {mode!="idle"} 范围函数 rate(...[5m]) 聚合操作 sum by (instance) 聚合结果:CPU 使用率(按实例) {instance="10.0.0.1:9100"} → 0.35 聚合维度控制 by (instance) → 保留 instance 标签,按实例分组聚合 without (cpu) → 去除 cpu 标签,按剩余标签聚合

4.5 综合案例:诊断节点资源瓶颈

结合以上知识,编写一个完整的资源瓶颈诊断查询,用于找出集群中 CPU 使用率超过 80% 的节点:

# 步骤1:计算每个节点的 CPU 使用率(范围向量 + rate + 聚合)
node_cpu_usage_rate = 1 - avg(rate(node_cpu_seconds_total{mode="idle"}[5m])) by (instance)

# 步骤2:比较操作符过滤出超过阈值的节点
node_cpu_usage_rate > 0.8

# 步骤3:使用 topk 找出最严重的 Top 3 节点
topk(3, node_cpu_usage_rate)
推荐实践: 在编写 PromQL 时,遵循“先过滤、再计算、后聚合”的顺序。先使用选择器缩小数据范围,再用范围向量函数(如 rate、increase)计算速率,最后用聚合函数按业务维度汇总。这种顺序能显著降低查询的计算开销。

下表总结了本章四个核心概念在资源配额诊断中的典型组合模式:

诊断场景 向量类型 选择器 操作符 聚合
节点 CPU 过载 范围向量 {mode="idle"} 1 - ... avg by(instance)
命名空间内存配额 即时向量 {namespace=~".+"} / sum by(namespace)
Pod 重启风暴 范围向量 {pod!=""} > 5 topk(10, ...)
磁盘 IO 等待 范围向量 {device=~"sd[a-z]"} / avg by(instance)

掌握即时向量与范围向量的选择、选择器的精确匹配、操作符的灵活组合以及聚合操作的维度控制,你已经具备了编写生产级 PromQL 查询的基础能力。下一层知识将围绕 PromQL 的内置函数展开,进一步扩展瓶颈诊断的表达力。