3. PromQL 入门:基本语法、数据类型与选择器基础
PromQL(Prometheus Query Language)是 Prometheus 生态中用于实时数据查询与分析的核心语言。在容量水位阈值设定与复核场景中,PromQL 是连接原始指标与可执行告警规则的桥梁。本章将系统讲解 PromQL 的基本语法结构、四种核心数据类型以及选择器的使用方式,为后续编写精确的容量阈值表达式打下坚实基础。
3.1 PromQL 基本语法结构
PromQL 表达式由指标名称、标签选择器、时间范围、运算符和函数组合而成。一个完整的 PromQL 查询通常遵循以下结构:
<metric_name>{<label_selector>}[<time_duration>] @ <timestamp>
各组成部分说明:
| 组成部分 | 说明 | 示例 |
|---|---|---|
| 指标名称 | 标识被监控的指标项,如 CPU 使用率、内存用量 | node_cpu_seconds_total |
| 标签选择器 | 用花括号包裹,用于过滤特定维度的数据 | {mode="idle", instance="web-01"} |
| 时间范围 | 方括号内指定回溯的时间窗口,仅用于 Range Vector | [5m] |
| 时间偏移 | 使用 @ 符号指定查询的基准时间点 |
@ 1710000000 |
提示:在容量水位阈值场景中,指标名称通常对应资源使用率(如
container_cpu_usage_seconds_total),标签选择器用于区分不同服务、实例或容器组。
3.2 四种核心数据类型
PromQL 定义了四种数据类型,理解它们的区别是正确编写查询的前提。在阈值复核中,最常使用的是 Instant Vector 和 Range Vector。
| 数据类型 | 定义 | 典型用途 | 示例 |
|---|---|---|---|
| Instant Vector | 一组时间序列,每个序列包含一个最新采样值 | 实时告警判断、当前水位快照 | node_memory_MemAvailable_bytes |
| Range Vector | 一组时间序列,每个序列包含一段时间窗口内的多个采样值 | 趋势分析、速率计算、分位数统计 | node_memory_MemAvailable_bytes[5m] |
| Scalar | 单一的数值常量,没有时间维度 | 阈值比较、数学运算中的固定值 | 1024、0.8 |
| String | 字符串常量,使用较少 | 标签值匹配、注释 | "production" |
关键区别:Instant Vector 返回的是“当前时刻的一个值”,而 Range Vector 返回的是“过去一段时间内的一组值”。在计算 CPU 使用率时,必须使用 Range Vector 获取时间窗口内的增量数据,再通过
rate() 函数转换为瞬时速率。
3.3 选择器基础
选择器用于从 Prometheus 时间序列数据库中精确筛选目标数据。根据匹配方式的不同,选择器分为以下四种:
- 精确匹配(=):标签值必须完全等于指定值。
node_cpu_seconds_total{mode="idle"} - 不等匹配(!=):标签值不等于指定值。
node_cpu_seconds_total{mode!="iowait"} - 正则匹配(=~):标签值匹配正则表达式。
node_cpu_seconds_total{mode=~"user|system"} - 正则排除(!~):标签值不匹配正则表达式。
node_cpu_seconds_total{mode!~"idle|steal"}
注意:正则表达式使用 RE2 语法,不支持回溯引用和环视。在容量场景中,常用正则匹配批量选择一组实例,例如
{instance=~"web-.*"} 匹配所有 web 前缀的实例。
3.4 选择器与数据类型的组合关系
选择器可以与 Instant Vector 和 Range Vector 组合使用,形成不同的查询模式。以下 SVG 图展示了选择器如何从指标存储中筛选数据,并生成不同的向量类型。
3.5 选择器在容量阈值场景中的应用
在容量水位阈值设定中,选择器的精确使用直接影响告警的准确性和覆盖范围。以下表格对比了不同选择器在典型场景中的应用:
| 场景 | 选择器示例 | 说明 |
|---|---|---|
| 单实例 CPU 水位 | node_cpu_seconds_total{instance="web-01", mode="user"} |
精确匹配特定实例和 CPU 模式 |
| 排除空闲 CPU | node_cpu_seconds_total{mode!="idle"} |
只关注非空闲 CPU 时间,用于计算使用率 |
| 批量选择 Web 实例 | node_cpu_seconds_total{instance=~"web-.*"} |
正则匹配所有 web 前缀实例,适合集群水位聚合 |
| 排除特定环境 | node_memory_MemAvailable_bytes{env!~"staging|dev"} |
只关注生产环境的内存可用量 |
3.6 常见错误与避坑指南
- 混淆 Instant Vector 与 Range Vector:在
rate()、increase()等函数中必须使用 Range Vector,传入 Instant Vector 会导致语法错误。 - 正则表达式性能问题:避免使用过于复杂的正则表达式,如
.*开头或嵌套分组,会导致查询性能下降。 - 空结果处理:当选择器没有匹配到任何时间序列时,查询返回空结果。在阈值告警中,空结果可能导致告警规则失效,建议使用
absent()函数兜底。 - 标签值大小写敏感:Prometheus 标签值区分大小写,
{mode="Idle"}与{mode="idle"}是不同的选择器。
实战建议:在编写容量阈值 PromQL 时,先在 Prometheus 的 Graph 页面中验证选择器返回的数据是否符合预期。使用
count() 函数可以快速检查匹配的时间序列数量,例如 count(node_cpu_seconds_total{mode="idle"}) 返回匹配的序列总数。