3、聚合查询入门:sum、avg、min、max、count、stddev、stdvar 基础用法

聚合查询是 PromQL 从原始时间序列中提取宏观趋势的核心手段。在自愈剧本中,告警触发延迟往往源于聚合粒度选择不当或聚合函数误用。本章将系统梳理 7 个最常用的聚合函数,建立正确的聚合思维模型。

3.1 聚合操作的本质

PromQL 聚合操作将一组时间序列按照 保留标签 合并为更少的序列。其通用语法为:

<aggr-op>([parameter,] <vector expression>) [without|by (<label list>)]
  • by:保留指定标签,按这些标签分组聚合。
  • without:移除指定标签,按剩余标签分组聚合。
SRE 经验: 在延迟排查场景中,by (instance, job) 比 without (cpu, mode) 更直观,因为显式声明保留维度能减少认知负担。

3.2 七种聚合函数速查表

函数 含义 适用场景 典型延迟排查用法
sum 求和 总量统计(QPS、总错误数) sum(rate(http_requests_total[5m]))
avg 平均值 负载均衡、平均延迟 avg(rate(http_request_duration_seconds_sum[5m]))
min 最小值 最空闲实例、最低延迟 min(node_load1)
max 最大值 最繁忙实例、峰值延迟 max(node_load1)
count 计数 实例数量、健康实例数 count(up == 1)
stddev 标准差 离散程度、抖动检测 stddev(rate(http_requests_duration_seconds_bucket[5m]))
stdvar 方差 波动幅度、异常扩散 stdvar(node_network_receive_bytes_total[1m])

3.3 聚合函数执行流程

下图展示了 PromQL 聚合查询从原始数据到聚合结果的完整链路:

PromQL 聚合查询执行流程 原始时间序列 标签选择器过滤 聚合函数计算 by / without 分组 聚合结果序列 关键理解: 聚合函数作用于过滤后的所有序列,分组决定哪些标签保留。分组错误是告警延迟的常见根因。

3.4 分组语义对比:by vs without

分组是聚合查询中最容易出错的环节。以下对比帮助理解两种分组方式的差异:

分组方式 示例 保留标签 结果序列数
by (job) sum(rate(...)) by (job) 仅 job 等于 job 数量
without (instance) sum(rate(...)) without (instance) 除 instance 外所有标签 等于剩余标签组合数
by (job, instance) avg(...) by (job, instance) job 和 instance 等于 job × instance 组合数
告警延迟陷阱: 使用 without (instance) 时,如果原始序列包含 cpu、mode 等标签,结果序列数可能远超预期,导致聚合计算变慢,间接增加告警触发延迟。

3.5 聚合函数与自愈剧本的关联

在自愈剧本中,不同聚合函数服务于不同的诊断阶段:

  • sum:用于计算集群总 QPS 或总错误量,判断是否触发全局熔断。
  • avg:用于评估平均响应时间,判断整体服务质量是否劣化。
  • max / min:用于发现热点实例(max)或空闲实例(min),辅助流量调度决策。
  • count:用于监控存活实例数,当 count(up == 1) < 预期值 时触发扩容。
  • stddev / stdvar:用于检测延迟抖动,当标准差突增时预示系统进入不稳定状态。

3.6 聚合函数选择决策树

以下决策树帮助 SRE 在延迟排查中快速选择正确的聚合函数:

聚合函数选择决策树 需要聚合什么? 总量/累计值 平均值/趋势 极值/离散度 → 使用 sum → 使用 avg 极值还是抖动? → min/max → stddev/var 提示:延迟排查优先使用 avg 观察整体趋势,再用 max/stddev 定位异常实例。

3.7 实战:聚合查询在延迟排查中的应用

假设有一个自愈剧本监控 HTTP 服务延迟,原始指标为 http_request_duration_seconds(Summary 类型)。以下聚合查询覆盖从宏观到微观的排查链路:

# 1. 全局平均延迟(宏观健康检查)
avg(rate(http_request_duration_seconds_sum[5m])) / avg(rate(http_request_duration_seconds_count[5m]))

# 2. 按实例查看最大延迟(定位热点)
max by (instance) (rate(http_request_duration_seconds_sum[5m]) / rate(http_request_duration_seconds_count[5m]))

# 3. 延迟抖动检测(stddev 突增预示不稳定)
stddev by (instance) (rate(http_request_duration_seconds_sum[5m]) / rate(http_request_duration_seconds_count[5m]))

# 4. 健康实例计数(判断是否需要扩容)
count by (job) (up == 1)
自愈剧本集成建议: 将上述查询封装为 Prometheus 记录规则(Recording Rules),预计算后供告警规则快速读取,可显著降低告警触发延迟。

3.8 常见错误与避坑指南

  • 错误: 对 Counter 类型直接使用 sum 而不加 rate,导致结果持续增长,无法反映当前状态。
  • 错误: 忘记指定 by 或 without,导致所有序列合并为一条,丢失实例维度信息。
  • 错误: 在 stddev 中使用未经 rate 处理的原始 Counter,标准差失去意义。
  • 正确做法: 聚合前先通过 rate 或 increase 将 Counter 转换为速率,再应用聚合函数。