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值和一个毫秒精度的时间戳。
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 触发器才能得到一个明确的阈值比较结果。
常用聚合运算符:
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() 子句可以保留特定标签维度,实现更精细的扩缩容策略。