Prometheus 基础回顾:PromQL 核心概念、指标类型与数据模型

在深入 KEDA 触发器调优之前,必须牢固掌握 Prometheus 的基石。KEDA 的 Prometheus 触发器本质上是一个 PromQL 查询的封装,你对指标类型、数据模型和查询语言的理解深度,直接决定了触发器配置的准确性与性能。本节将系统梳理这些核心概念。

1. 数据模型:时间序列的构成

Prometheus 存储的所有数据都是时间序列(Time Series)。一个时间序列由一组指标名称(Metric Name)和一组标签(Labels)唯一标识。

核心公式:
<metric_name>{<label_name>="<label_value>", ...}

例如:http_requests_total{method="GET", endpoint="/api/v1", status="200"}

数据模型的关键要素:

  • Metric Name:描述被监控量的语义,如 http_requests_total、node_cpu_seconds_total。
  • Labels:键值对,用于维度划分。每个不同的标签组合构成一个独立的时间序列。
  • Sample:时间序列中的单个数据点,包含一个 float64 值和一个毫秒精度的时间戳。
Prometheus 时间序列数据模型 时间序列数据模型 Metric Name http_requests_total Labels (维度) {method="GET", status="200"} Sample (数据点) 值: 1024 @ T1 时间线:同一 Metric + Labels 组合的连续样本 T1: 1024 T2: 1056 T3: 1102 T4: 1145 T5: 1190 每个时间戳对应一个样本值,构成完整的时间序列

2. 指标类型:四种核心类型

Prometheus 客户端库提供四种核心指标类型。理解它们的语义差异,是编写正确 PromQL 和配置 KEDA 触发器的前提。

类型 语义 典型场景 KEDA 触发器常用操作
Counter 只增不减的累计值(重启时归零) 请求总数、错误总数、任务完成数 rate() / increase() 计算速率
Gauge 可增可减的瞬时值 CPU 使用率、内存使用量、队列深度 直接取值或使用 avg() / max()
Histogram 对观测值进行分桶计数和总和 请求延迟分布、响应大小分布 histogram_quantile() 计算百分位
Summary 类似 Histogram,但由客户端计算分位数 预定义分位数的延迟监控 直接使用 quantile 标签
实践要点:KEDA 的 Prometheus 触发器通常使用 rate() 处理 Counter 类型指标来获取每秒请求数,使用 avg_over_time() 处理 Gauge 类型指标来获取平均负载。对于延迟敏感的扩缩容场景,优先使用 Histogram 的 histogram_quantile() 而非 Summary,因为 Summary 的分位数无法在服务端进行聚合计算。

3. PromQL 核心概念:选择器与聚合

PromQL(Prometheus Query Language)是数据检索和处理的唯一语言。KEDA 触发器配置中的 query 字段就是一个 PromQL 表达式。

3.1 即时向量与范围向量

  • Instant Vector:查询某个时间戳的一组时间序列的最新样本。例如:http_requests_total{method="GET"}
  • Range Vector:查询某个时间范围内的一组时间序列的样本集合。例如:http_requests_total{method="GET"}[5m]
常见错误:在 KEDA 触发器中使用 rate() 或 avg_over_time() 时,必须传入 Range Vector。如果误传 Instant Vector,查询会立即失败。例如:rate(http_requests_total{method="GET"}[5m]) 是正确的,而 rate(http_requests_total{method="GET"}) 是错误的。

3.2 常用 PromQL 函数

函数 适用类型 说明 KEDA 场景示例
rate() Counter 计算时间窗口内每秒平均增长率 计算 QPS:rate(http_requests_total[1m])
increase() Counter 计算时间窗口内的增量 计算 5 分钟请求增量:increase(http_requests_total[5m])
avg_over_time() Gauge 计算时间窗口内的平均值 平均 CPU 使用率:avg_over_time(cpu_usage[5m])
max_over_time() Gauge 计算时间窗口内的最大值 峰值内存:max_over_time(memory_usage[5m])
histogram_quantile() Histogram 从直方图计算指定分位数 P99 延迟:histogram_quantile(0.99, rate(http_request_duration_seconds_bucket[5m]))

4. 聚合操作:降维与分组

当查询返回多个时间序列时,需要使用聚合操作将其合并为单个值,KEDA 触发器才能得到一个明确的阈值比较结果。

PromQL 聚合操作流程 PromQL 聚合:从多序列到单值 输入:多个序列 pod_a: 100 pod_b: 150 pod_c: 120 聚合操作 sum( ) avg( ) / max( ) / min( ) 输出:单个值 sum = 370 avg = 123.3 KEDA 触发器要求:查询结果必须是一个 Instant Vector 且仅包含一个样本 使用 sum()、avg() 等聚合函数将多 pod 指标合并为集群级指标

常用聚合运算符:

  • sum():求和,适用于累加所有实例的请求数。
  • avg():求平均值,适用于计算平均延迟或平均利用率。
  • max() / min():取最大/最小值,适用于识别热点或瓶颈。
  • count():计数,适用于统计满足条件的实例数量。
KEDA 触发器配置示例:
triggers:
- type: prometheus
  metadata:
    serverAddress: http://prometheus:9090
    query: |
      sum(
        rate(http_requests_total{job="my-app", status="5xx"}[2m])
      ) / 
      sum(
        rate(http_requests_total{job="my-app"}[2m])
      ) > 0.05
    threshold: "1.0"

该查询计算 5xx 错误率,当错误率超过 5% 时触发扩容。注意使用 sum() 将所有实例的请求合并,再计算比率。

5. 指标类型与 PromQL 的映射关系

不同指标类型在 PromQL 中的处理方式有显著差异,错误使用会导致语义错误或查询失败。

指标类型 推荐 PromQL 模式 避免的操作 原因
Counter rate(metric[5m]) 或 increase(metric[5m]) 直接使用原始值 Counter 持续增长,原始值无意义;速率才反映真实负载
Gauge avg_over_time(metric[5m]) 或 max(metric) rate(metric[5m]) Gauge 可增可减,rate() 语义不适用,会返回无意义结果
Histogram histogram_quantile(0.99, rate(metric_bucket[5m])) 直接使用 metric_sum 或 metric_count 原始 sum/count 无法反映分布;必须结合 rate() 和 histogram_quantile()
Summary metric{quantile="0.99"} histogram_quantile() Summary 已由客户端计算分位数,服务端无法再次聚合
最佳实践:在编写 KEDA 触发器的 PromQL 时,始终在 Prometheus UI 的 Graph 页面中先验证查询结果。确保返回的 Instant Vector 只有一个值,并且该值在预期范围内波动。使用 sum() 或 avg() 聚合时,注意 by() 子句可以保留特定标签维度,实现更精细的扩缩容策略。