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 图展示了即时向量与范围向量在时间轴上的数据采样差异:
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 图展示了从原始指标到聚合结果的完整数据流:
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 的内置函数展开,进一步扩展瓶颈诊断的表达力。