3. Prometheus 基础回顾:PromQL 核心语法、数据模型与常用聚合算子
在深入蓝绿发布故障排查之前,必须牢固掌握 Prometheus 的数据模型与查询语言 PromQL。本节将系统梳理 Metric、Label、Sample 三大核心概念,以及 PromQL 的聚合算子与常用函数,为后续自动化告警与根因分析打下基础。
3.1 数据模型:Metric、Label、Sample
Prometheus 存储的所有时间序列数据由三个基本元素唯一标识:
| 元素 | 说明 | 示例 |
|---|---|---|
| Metric(指标名) | 描述被监控对象特征的名称,通常包含命名空间 | http_requests_total |
| Label(标签) | 键值对,用于区分同一指标下的不同维度 | method="GET", status="200" |
| Sample(样本) | 时间戳 + 浮点数值,构成时间序列的一个数据点 | t=1710000000, v=1024 |
关键理解: 一个完整的时间序列由
metric_name + {label_key="label_value", ...} 唯一确定。例如 http_requests_total{method="POST", instance="web-01"} 是一个独立的时间序列。
3.2 PromQL 核心语法
PromQL 提供四种基本查询类型,用于从时间序列中提取数据:
- 即时查询(Instant Query): 返回查询时间点的最新样本值。
- 范围查询(Range Query): 返回一段时间窗口内的所有样本值。
- 偏移查询(Offset Modifier): 查询过去某个时间点的数据。
- 子查询(Subquery): 对范围向量进行二次聚合。
3.2.1 选择器语法
# 精确匹配
http_requests_total{job="api-server", method="GET"}
# 正则匹配(=~ 匹配正则,!~ 排除正则)
http_requests_total{instance=~"web-.*"}
# 负向匹配
http_requests_total{status!~"5.."}
# 范围向量(查询过去 5 分钟)
http_requests_total[5m]
3.2.2 常用操作符
| 类型 | 操作符 | 说明 |
|---|---|---|
| 算术 | + - * / % ^ |
标量与向量、向量与向量之间的运算 |
| 比较 | == != < > <= >= |
返回布尔值(0 或 1),常用于告警规则 |
| 逻辑 | and or unless |
集合运算,用于过滤或合并时间序列 |
| 向量匹配 | on() group_left() group_right() |
多对一、一对多匹配,用于多指标关联 |
蓝绿发布场景示例: 比较蓝绿两组的请求成功率差异:
(sum(rate(http_requests_total{group="blue", status=~"2.."}[5m])) / sum(rate(http_requests_total{group="blue"}[5m]))) - (sum(rate(http_requests_total{group="green", status=~"2.."}[5m])) / sum(rate(http_requests_total{group="green"}[5m])))
3.3 常用聚合算子
聚合算子用于将多个时间序列合并为单个序列,是故障排查中计算集群整体状态的核心工具。
| 算子 | 作用 | 蓝绿发布典型用法 |
|---|---|---|
sum() |
求和 | 计算总请求量 |
avg() |
平均值 | 计算平均响应时间 |
min() / max() |
最小值 / 最大值 | 找出最慢或最快的实例 |
count() |
计数 | 统计健康实例数量 |
stddev() / stdvar() |
标准差 / 方差 | 检测流量分布是否均匀 |
topk() / bottomk() |
前 K 个 / 后 K 个 | 定位异常实例 |
quantile() |
分位数 | 计算 P99 延迟 |
rate() / irate() |
每秒增长率 | 计算 QPS、错误率 |
3.3.1 聚合算子使用示例
# 按 group 维度聚合,计算每个组的 QPS
sum(rate(http_requests_total[5m])) by (group)
# 计算全局 P99 延迟,排除异常值
histogram_quantile(0.99, sum(rate(http_request_duration_seconds_bucket[5m])) by (le))
# 找出响应时间超过 2s 的实例
topk(5, avg(rate(http_request_duration_seconds_sum[5m])) by (instance))
3.4 PromQL 数据模型与查询流程
下图展示了 Prometheus 从抓取数据到 PromQL 查询返回结果的完整链路:
3.5 蓝绿发布中的 PromQL 实战模式
在蓝绿发布故障排查中,以下 PromQL 模式会频繁出现:
常见陷阱: 使用
rate() 时,如果时间窗口小于 scrape 间隔的 4 倍,可能导致数据不准确。建议范围向量长度 ≥ 4 × scrape_interval。
# 模式 1:对比两组流量比例
sum(rate(http_requests_total{group="blue"}[5m])) / sum(rate(http_requests_total[5m]))
# 模式 2:检测错误率突增
sum(rate(http_requests_total{status=~"5.."}[5m])) / sum(rate(http_requests_total[5m])) > 0.05
# 模式 3:计算健康实例占比
count(up{group="green"} == 1) / count(up{group="green"})
# 模式 4:P99 延迟对比(蓝 vs 绿)
histogram_quantile(0.99, sum(rate(http_request_duration_seconds_bucket{group="blue"}[5m])) by (le)) -
histogram_quantile(0.99, sum(rate(http_request_duration_seconds_bucket{group="green"}[5m])) by (le))
3.6 常用函数速查
| 函数 | 用途 | 蓝绿发布场景 |
|---|---|---|
rate() |
计算 Counter 类型指标的每秒平均增长率 | QPS、错误率 |
irate() |
计算瞬时增长率(对短时突变更敏感) | 快速检测流量抖动 |
increase() |
计算时间窗口内的增量 | 统计切换后的请求总量 |
delta() |
计算 Gauge 类型指标的变化量 | 内存、CPU 变化趋势 |
predict_linear() |
基于线性回归预测未来值 | 预测磁盘耗尽时间 |
label_replace() |
正则替换标签值 | 统一蓝绿两组标签格式 |
最佳实践: 在蓝绿发布自动化脚本中,将上述 PromQL 封装为告警规则或预计算记录规则(Recording Rules),可以大幅降低故障排查时的查询延迟。