2. PromQL 基础回顾:数据类型、选择器与聚合操作
在进入水位录制规则设计之前,必须牢固掌握 PromQL 的四种数据类型、标签选择机制以及基础聚合操作。这些是构建任何录制规则表达式的底层语言基础。
2.1 PromQL 四种数据类型
PromQL 表达式求值后返回以下四种类型之一。理解它们的区别是正确使用函数与操作符的前提。
| 类型 | 英文名称 | 说明 | 典型示例 |
|---|---|---|---|
| 瞬时向量 | Instant Vector | 一组时间序列,每个序列包含一个最新采样值,时间戳相同 | node_cpu_seconds_total |
| 区间向量 | Range Vector | 一组时间序列,每个序列包含一段时间窗口内的多个采样值 | node_cpu_seconds_total[5m] |
| 标量 | Scalar | 一个单纯的数字浮点值,没有维度(标签) | 1024、3.14 |
| 字符串 | String | 一个简单的字符串值,在 PromQL 中主要用于标签操作,不常用作查询结果 | "prod" |
水位规则关键点:录制规则(Recording Rule)的右侧表达式必须返回 瞬时向量。区间向量不能直接用于规则赋值,必须先通过聚合函数(如
avg_over_time)降维成瞬时向量。
2.2 选择器与标签匹配
选择器用于从时间序列数据库中筛选出目标序列。标签匹配是 PromQL 最灵活的过滤手段,分为三种匹配操作符。
2.2.1 匹配操作符对比
| 操作符 | 含义 | 示例 | 匹配行为 |
|---|---|---|---|
= |
完全相等 | job="api-server" |
标签值必须精确匹配 |
!= |
不相等 | job!="api-server" |
排除指定标签值的所有序列 |
=~ |
正则匹配 | instance=~"10\\.0\\.1\\..*" |
标签值匹配正则表达式 |
!~ |
正则排除 | instance!~"10\\.0\\.1\\..*" |
标签值不匹配正则表达式 |
2.2.2 选择器语法结构
# 瞬时向量选择器:直接指定指标名 + 标签过滤
node_memory_MemAvailable_bytes{env="prod", instance=~"web-.*"}
# 区间向量选择器:在瞬时向量基础上加 [时间窗口]
node_memory_MemAvailable_bytes{env="prod"}[5m]
# 空标签选择器:匹配所有包含该标签的序列(无论值是什么)
node_memory_MemAvailable_bytes{env=""}
# 标签存在性匹配:使用正则 .* 匹配任意值
node_memory_MemAvailable_bytes{env=~".*"}
性能建议:录制规则中尽量使用
= 精确匹配代替 =~ 正则匹配。正则匹配在标签基数高时会导致查询引擎扫描大量序列,增加规则评估延迟。
2.3 基础聚合操作
聚合操作将多个时间序列合并为更少的序列,是水位规则中“降维”和“归一化”的核心手段。
2.3.1 常用聚合函数
| 函数 | 作用 | 水位场景示例 |
|---|---|---|
sum |
求和 | 聚合所有实例的 CPU 使用总量 |
avg |
平均值 | 计算集群平均内存使用率 |
max |
最大值 | 找出实例组中的最高水位 |
min |
最小值 | 找出实例组中的最低水位 |
count |
计数 | 统计满足条件的实例数量 |
quantile |
分位数 | 计算 P99 延迟水位 |
stddev |
标准差 | 评估水位波动离散程度 |
2.3.2 聚合语法:by 与 without
聚合时必须指定保留哪些标签维度。两种子句控制维度保留方式:
by:显式列出要保留的标签,其余标签被丢弃。without:显式列出要移除的标签,其余标签全部保留。
# 按 job 和 env 分组求和,丢弃 instance 等其余标签
sum by (job, env) (node_memory_MemAvailable_bytes)
# 等价写法:移除 instance 和 device 标签,保留其他所有标签
sum without (instance, device) (node_memory_MemAvailable_bytes)
常见陷阱:忘记使用
by 或 without 时,聚合会返回一个无标签的标量结果。在水位录制规则中,这会导致丢失所有维度信息,无法按实例或集群进行后续告警分派。始终显式指定保留维度。
2.4 数据类型与聚合流程总览
下图展示了从原始指标到录制规则结果的完整数据流,以及各阶段涉及的数据类型转换:
2.5 实战案例:从原始指标到水位规则
以下是一个完整的水位录制规则表达式拆解,综合运用了选择器、区间向量和聚合操作:
# 规则名称:instance:node_memory_usage:ratio_avg5m
# 表达式含义:每台实例过去5分钟的平均内存使用率
# 步骤1:原始瞬时向量(内存总量)
node_memory_MemTotal_bytes{job="node-exporter"}
# 步骤2:原始瞬时向量(可用内存)
node_memory_MemAvailable_bytes{job="node-exporter"}
# 步骤3:计算瞬时使用率(标量运算,结果仍为瞬时向量)
(1 - node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes)
# 步骤4:转换为区间向量,取5分钟平均值
avg_over_time(
(1 - node_memory_MemAvailable_bytes{job="node-exporter"}
/ node_memory_MemTotal_bytes{job="node-exporter"})[5m]
)
# 步骤5:最终录制规则(已包含 by 保留 instance 标签)
- record: instance:node_memory_usage:ratio_avg5m
expr: |
avg by (instance) (
avg_over_time(
(1 - node_memory_MemAvailable_bytes{job="node-exporter"}
/ node_memory_MemTotal_bytes{job="node-exporter"})[5m]
)
)
水位规则设计要点:
- 始终使用
avg_over_time等区间聚合函数将原始数据平滑化,避免瞬时抖动导致水位误判。 - 聚合时通过
by明确保留维度(如instance、job),确保规则结果可被后续告警规则按实例路由。 - 标签选择器尽量精确,避免正则匹配带来的性能开销。