2. PromQL 基础回顾:数据类型与基础查询语法

在深入告警表达式复核之前,必须牢固掌握 PromQL 的四种核心数据类型及其查询语法。告警规则的本质是 PromQL 表达式,任何类型误用或语法错误都会导致告警失效或误报。本节将系统梳理数据类型与基础查询结构,为后续的表达式复核打下坚实基础。

2.1 四种数据类型概览

PromQL 严格区分四种数据类型,它们在告警表达式中的角色与使用场景截然不同:

数据类型 英文名称 含义 告警场景典型用途
瞬时向量 Instant Vector 一组时间序列,每个序列包含一个最新采样值 告警条件判断(如 cpu_usage > 0.9)
区间向量 Range Vector 一组时间序列,每个序列包含一段时间内的多个采样值 趋势计算、速率、变化率(如 rate(http_requests_total[5m]))
标量 Scalar 一个单一的数值 阈值常量、偏移量、数学运算中的常数
字符串 String 一个字符串值(目前使用极少) 告警标签值、注释(非核心计算)
⚠️ 告警复核关键点: 告警规则中 expr 字段的返回值必须是瞬时向量。如果表达式返回区间向量或标量,Prometheus 将无法正确评估告警状态,导致规则失效。

2.2 瞬时向量(Instant Vector)—— 告警表达式的基石

瞬时向量是 PromQL 中最常用的数据类型,也是告警规则 expr 的唯一合法返回类型。它由指标名和标签唯一标识,每个时间序列只保留最新的一个样本值。

基础查询语法:

<metric_name>{<label_selectors>}
  • 指标名:如 node_cpu_seconds_total、http_requests_total。
  • 标签选择器:用 {} 包裹,支持 =(精确匹配)、!=(不匹配)、=~(正则匹配)、!~(正则不匹配)。

示例:

# 查询所有 node_cpu_seconds_total 序列
node_cpu_seconds_total

# 查询特定实例、特定模式的 CPU 序列
node_cpu_seconds_total{instance="web-01:9100", mode=~"user|system"}

# 排除空闲模式
node_cpu_seconds_total{mode!="idle"}
💡 复核技巧: 在告警规则中,务必检查标签选择器是否过于宽泛(可能引入无关序列)或过于严格(可能遗漏目标序列)。使用 count() 函数可以快速验证返回的序列数量是否符合预期。

2.3 区间向量(Range Vector)—— 时间窗口计算的基础

区间向量在瞬时向量的基础上增加了时间维度,通过在指标名后附加 [duration] 来指定回溯窗口。区间向量本身不能直接用于告警条件判断,必须配合 rate()、increase()、avg_over_time() 等聚合函数转换为瞬时向量。

基础查询语法:

<metric_name>{<label_selectors>}[<duration>]

示例:

# 查询过去 5 分钟内所有 HTTP 请求的原始数据点
http_requests_total[5m]

# 查询特定路由过去 1 小时的请求数据
http_requests_total{route="/api/v1/health"}[1h]
时间窗口 常用场景 告警复核注意事项
[1m] 高灵敏度告警(如延迟突增) 窗口过短易受瞬时抖动影响,产生告警风暴
[5m] 通用速率/增长率计算 需确保采集间隔 × 样本数 ≥ 窗口,避免数据不足
[1h] 慢速趋势分析(如磁盘增长) 窗口过长可能导致告警响应延迟
⚠️ 常见错误: 在告警规则中直接使用区间向量作为 expr,例如 http_requests_total[5m] > 100。这是非法的,因为区间向量不能与标量直接比较。必须先用 rate() 或 increase() 转换为瞬时向量。

2.4 标量(Scalar)与字符串(String)

标量在告警表达式中主要作为阈值常量出现,例如 0.9、1000。标量可以与瞬时向量进行算术运算或比较运算。

字符串在 PromQL 中功能有限,主要用于标签值或注释,不参与数值计算。在告警规则中,字符串通常出现在 labels 和 annotations 字段中,而非 expr 字段。

# 标量示例:比较运算
node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes < 0.1

# 字符串示例(告警注释中)
annotations:
  summary: "Instance {{ $labels.instance }} 内存不足"

2.5 数据类型转换与查询结构总览

下图展示了四种数据类型之间的转换关系以及告警表达式的典型查询流程:

PromQL 数据类型转换与告警查询流程 TSDB 时间序列 区间向量 瞬时向量 标量 告警规则 expr 查询 + [时间窗口] 直接查询 rate() / increase() / avg_over_time() 比较运算 作为阈值参与比较 🔑 核心约束: 告警规则 expr 必须返回瞬时向量;区间向量必须经聚合函数转换后才能使用;标量仅作为阈值或运算因子。

2.6 基础查询语法速查表

查询类型 语法示例 返回类型 是否可用于告警 expr
指标名查询 node_cpu_seconds_total 瞬时向量 ✅ 是
标签过滤查询 node_cpu_seconds_total{mode="user"} 瞬时向量 ✅ 是
正则匹配查询 node_cpu_seconds_total{mode=~"user|system"} 瞬时向量 ✅ 是
区间查询 node_cpu_seconds_total[5m] 区间向量 ❌ 否(需转换)
标量运算 node_memory_MemAvailable_bytes / 1024 瞬时向量 ✅ 是
比较运算 node_load1 > 0.8 瞬时向量 ✅ 是
📌 复核要点总结:
  • 确认告警 expr 返回类型为瞬时向量。
  • 区间向量必须配合 rate()、increase()、avg_over_time() 等函数使用。
  • 标签选择器需精确匹配目标序列,避免范围过大或过小。
  • 时间窗口长度应与告警灵敏度需求匹配,避免数据不足或响应延迟。