3. PromQL 聚合操作:sum、avg、min、max、count、topk、quantile 等聚合函数详解
在 PromQL 中,聚合操作是将一组时间序列合并为单一序列的核心手段。当您面对成百上千个实例(如所有 Web 服务器的 CPU 使用率)时,聚合函数能将原始数据转化为可决策的黄金指标(如“集群平均 CPU 使用率”或“P99 延迟”)。
3.1 聚合操作基础语法
所有聚合函数遵循统一语法结构:
<聚合函数>([参数,] <PromQL 表达式>) [without|by (<标签列表>)]
- 聚合函数:sum、avg、min、max、count、topk、quantile 等。
- 参数:仅 topk、quantile 等需要额外数值参数。
- without / by:控制保留或移除哪些标签维度。
💡 关键区别:
by (instance) 表示“按 instance 分组聚合”,结果中保留 instance 标签;without (instance) 表示“聚合时排除 instance 标签”,结果中不包含 instance。
3.2 核心聚合函数速查表
| 函数 | 作用 | 典型场景 | 示例 |
|---|---|---|---|
| sum | 求和 | 总请求量、总内存使用 | sum(http_requests_total) |
| avg | 平均值 | 平均延迟、平均 CPU 使用率 | avg(node_cpu_seconds_total) |
| min | 最小值 | 最空闲节点、最低延迟 | min(node_memory_MemFree_bytes) |
| max | 最大值 | 最繁忙节点、最高延迟 | max(http_request_duration_seconds) |
| count | 计数 | 在线实例数、满足条件的节点数 | count(up == 1) |
| topk | 取前 K 个最大值 | Top 5 最慢接口、Top 3 最耗 CPU 容器 | topk(5, http_request_duration_seconds) |
| quantile | 分位数(0~1) | P50、P90、P99 延迟 | quantile(0.99, http_request_duration_seconds) |
3.3 聚合函数详解与实战
3.3.1 sum —— 最常用的求和
sum 将多个时间序列的样本值相加。常用于计算总量指标:
# 所有实例的总请求数
sum(http_requests_total)
# 按状态码分组的总请求数
sum by (status_code) (http_requests_total)
3.3.2 avg —— 消除实例差异
avg 计算平均值,适合评估整体健康度:
# 集群平均 CPU 使用率
avg(rate(node_cpu_seconds_total{mode="idle"}[5m]))
3.3.3 min / max —— 边界检测
min 和 max 用于发现异常极端值:
# 找出延迟最高的服务
max(http_request_duration_seconds)
# 找出剩余内存最少的节点
min(node_memory_MemFree_bytes)
3.3.4 count —— 实例计数
count 统计序列数量,常用于可用性监控:
# 当前健康的实例数
count(up == 1)
# 按 region 统计在线实例
count by (region) (up == 1)
3.3.5 topk —— 聚焦头部异常
topk(k, expr) 返回数值最大的 K 个序列,保留原始标签:
# 延迟最高的 5 个端点
topk(5, http_request_duration_seconds)
⚠️ 注意:
topk 和 bottomk 返回的是原始序列(带标签),不是聚合后的单条线。在图表中会显示多条线。
3.3.6 quantile —— 延迟分布黄金函数
quantile(φ, expr) 计算 φ 分位数(0 ≤ φ ≤ 1)。这是 SRE 黄金指标中延迟分布的核心:
# P99 延迟(99% 的请求在此值以下)
quantile(0.99, rate(http_request_duration_seconds_bucket[5m]))
# 同时计算 P50、P90、P99
quantile(0.50, rate(http_request_duration_seconds_bucket[5m]))
quantile(0.90, rate(http_request_duration_seconds_bucket[5m]))
quantile(0.99, rate(http_request_duration_seconds_bucket[5m]))
3.4 聚合操作流程与标签控制
下图展示了从原始时间序列到聚合结果的完整流程,以及 by 与 without 对标签维度的不同影响:
3.5 聚合操作实战对比表
| 场景 | 推荐函数 | 示例表达式 | 输出说明 |
|---|---|---|---|
| 集群总 QPS | sum | sum(rate(http_requests_total[1m])) |
所有实例请求速率之和 |
| 平均响应时间 | avg | avg(rate(http_request_duration_seconds_sum[1m]) / rate(http_request_duration_seconds_count[1m])) |
所有实例的平均延迟 |
| 最慢接口 Top 5 | topk | topk(5, avg by (handler) (rate(http_request_duration_seconds_sum[5m]) / rate(http_request_duration_seconds_count[5m]))) |
返回 5 个最慢 handler |
| P99 延迟 | quantile | quantile(0.99, rate(http_request_duration_seconds_bucket[5m])) |
99% 请求在此值以下 |
| 在线实例数 | count | count(up == 1) |
健康实例总数 |
| 最大内存使用 | max | max(container_memory_usage_bytes) |
最耗内存的容器 |
3.6 常见陷阱与最佳实践
✅ 最佳实践:
- 先 rate 再聚合:对 Counter 类型指标,先
rate()或increase()再聚合,避免因重启导致数据失真。 - 明确标签维度:使用
by保留关键维度(如job、service),避免过度聚合丢失排查线索。 - quantile 配合 histogram:分位数计算必须基于
_bucket指标,直接对 Gauge 使用quantile无意义。
⚠️ 常见陷阱:
- sum 后丢失实例维度:
sum(up)只告诉你总数,无法知道哪个实例挂了。建议配合by (instance)或保留告警标签。 - topk 在 dashboard 中闪烁:由于 topk 每次只取前 K,当数据波动时,图表中的序列会频繁切换,建议结合
avg_over_time平滑。 - count 与 count_values 混淆:
count统计序列数量;count_values统计每个样本值出现的次数,二者完全不同。
3.7 聚合函数选择决策流程
当您面对一个监控需求时,可按以下流程快速选择正确的聚合函数:
3.8 录制规则中的聚合应用
在录制规则(Recording Rules)中,聚合函数常用于预计算高频使用的黄金指标,降低查询延迟:
# 示例:预计算集群 P99 延迟(每 30 秒更新)
groups:
- name: latency_aggregates
interval: 30s
rules:
- record: cluster:http_request_duration_seconds:p99
expr: quantile(0.99, rate(http_request_duration_seconds_bucket[5m]))
- record: cluster:http_requests_total:rate5m
expr: sum(rate(http_requests_total[5m]))
- record: instance:node_cpu_usage:avg
expr: avg by (instance) (rate(node_cpu_seconds_total{mode!="idle"}[5m]))
🎯 录制规则命名规范:
例如
<level>:<metric_name>:<operation>例如
cluster:http_requests_total:rate5m 表示“集群级别、5 分钟速率聚合”。