3. PromQL 聚合基础:回顾 sum、avg、max、min、count 等聚合函数

在构建误差预算告警体系之前,必须牢固掌握 PromQL 的聚合操作。聚合函数将一组时间序列(通常由 job、instance、service 等标签区分)合并为单一输出,是降噪和提炼关键指标的核心手段。

3.1 聚合函数速查表

以下五个聚合函数覆盖了 90% 的 SRE 监控场景。注意:聚合函数必须配合 by 或 without 子句使用,否则会丢失所有标签维度。

函数 行为描述 典型 SRE 场景
sum 对指定维度内的所有序列值求和 计算集群总 QPS、总错误数、总请求延迟
avg 计算指定维度内的算术平均值 平均 CPU 使用率、平均延迟、平均错误率
max 取指定维度内的最大值 最慢实例的延迟、最高 CPU 节点、最大错误数
min 取指定维度内的最小值 最低可用实例数、最小剩余磁盘空间
count 统计指定维度内的时间序列数量 存活实例数、健康 Pod 数、满足条件的节点数
关键区别:count 统计的是序列数量,而非数值总和。例如 count by (job) (up == 1) 返回每个 job 中健康实例的个数。

3.2 聚合行为与标签保留规则

聚合函数的行为由 by 和 without 子句控制,理解它们的差异是避免告警误报的基础。

  • by (label_list):显式声明保留哪些标签,其余标签全部丢弃。输出序列数 = 保留标签的笛卡尔积组合数。
  • without (label_list):显式声明丢弃哪些标签,其余标签全部保留。适用于排除高基数标签(如 instance)后观察服务级指标。
# 示例:按 job 聚合,丢弃 instance 标签
sum by (job) (rate(http_requests_total[5m]))

# 等价写法:丢弃 instance 和 pod 标签
sum without (instance, pod) (rate(http_requests_total[5m]))
常见陷阱:如果 by 子句中遗漏了关键标签(如 job),聚合结果会意外合并不同服务的指标,导致误差预算计算错误。始终先使用 count by (job, instance) 验证序列基数。

3.3 聚合在误差预算中的角色

在误差预算告警链中,聚合函数承担以下职责:

  1. 降维:将实例级指标(高基数)聚合为服务级指标(低基数),减少告警风暴。
  2. 归一化:通过 avg 或 sum / count 计算比率,如错误率 = sum(rate(errors_total)) / sum(rate(requests_total))。
  3. 边界检测:使用 max 或 min 发现异常实例,作为告警的补充信号。
实战建议:误差预算告警应优先使用 sum by (service) 聚合后的比率指标,而非原始实例级指标。这能过滤掉单实例抖动,聚焦服务整体健康度。

3.4 聚合函数行为对比图

下图展示了五个聚合函数在相同输入数据上的不同输出行为。输入为三个实例的 QPS 序列,聚合维度为 by (service)。

聚合函数行为对比:sum / avg / max / min / count 聚合函数行为对比(输入:3 个实例的 QPS) 输入时间序列(by service) instance-1: 120 QPS  |  instance-2: 200 QPS  |  instance-3: 80 QPS sum avg max min count 400 QPS (120+200+80) 133.3 QPS (400/3) 200 QPS (instance-2) 80 QPS (instance-3) 3 (实例数) 聚合行为要点 • sum 适合计算总量(总请求、总错误) • avg 适合计算平均负载(CPU、延迟) • max/min 用于边界检测(最慢/最快实例)

3.5 聚合与告警降噪的关联

在误差预算台账中,聚合函数直接影响告警的触发频率和准确度:

  • 过度聚合(如全局 sum 无 by)会掩盖局部故障,导致告警延迟。
  • 欠聚合(保留 instance 标签)会导致单实例抖动触发大量告警,产生告警风暴。
  • 最佳实践:误差预算告警使用 sum by (service, slo_class) 聚合,保留服务级和 SLO 分类标签,丢弃实例级标签。
降噪效果示例:假设 100 个实例中有 3 个实例错误率突增。使用 max by (instance) 会触发 3 条告警;使用 avg by (service) 可能不触发(被正常实例稀释);使用 sum by (service) (errors) / sum by (service) (requests) 计算服务级错误率,只有当整体错误率超过 SLO 阈值时才告警,实现最佳降噪。

3.6 聚合函数选择决策树

在编写误差预算查询时,按以下决策树选择聚合函数:

聚合函数选择决策树 聚合函数选择决策树(误差预算场景) 需要聚合什么? 总量(总请求/总错误) 使用 sum 平均值(延迟/CPU) 使用 avg 边界值(最慢/最快) 使用 max 或 min 误差预算告警推荐组合 错误率 = sum(rate(errors_total[5m])) by (service) / sum(rate(requests_total[5m])) by (service) 延迟 SLO = histogram_quantile(0.99, sum(rate(latency_bucket[5m])) by (le, service))

3.7 常见聚合错误与排查

错误模式 现象 根因 修复方法
遗漏 by 子句 聚合结果只有一个值,丢失所有标签 全局聚合,未保留维度 添加 by (job, service)
错误使用 avg 计算比率 比率值异常(如错误率 > 1) avg 对每个序列独立求平均后再平均 改用 sum / sum 计算比率
高基数标签未排除 聚合结果序列数过多,查询缓慢 without 未排除 instance、pod 使用 without (instance, pod)
count 误用于数值求和 结果远小于预期 count 统计序列数而非数值 改用 sum
调试技巧:在 Prometheus 的 Graph 页面中,先执行 count by (job, instance) (your_metric) 查看序列基数,再决定聚合维度。基数超过 100 的查询应考虑降维。