3. 聚合粒度定义:时间窗口与空间聚合对数据量的影响
在可观测性系统中,聚合粒度直接决定了存储成本、查询性能以及 SLI 的精度。聚合粒度分为两个维度:时间窗口(时间聚合)和 分组维度(空间聚合)。理解这两个维度如何影响数据量,是设计高效采集与存储策略的基础。
3.1 时间窗口:采样频率与数据压缩比
时间窗口定义了指标数据在时间轴上的聚合间隔。常见的窗口包括 1 秒、10 秒、1 分钟、5 分钟等。窗口越大,数据点越少,存储压力越小,但会丢失高频波动细节。
| 时间窗口 | 每秒数据点数(单指标) | 每日数据点数(单指标) | 典型场景 |
|---|---|---|---|
| 1s | 1 | 86,400 | 实时监控、高频交易、容器 CPU 突发 |
| 10s | 0.1 | 8,640 | 常规微服务延迟、错误率监控 |
| 1m | 0.0167 | 1,440 | 基础设施健康、长期趋势分析 |
| 5m | 0.0033 | 288 | 容量规划、月度报表、历史归档 |
关键权衡: 从 1s 窗口切换到 1m 窗口,数据量减少约 60 倍。但若 SLI 要求检测 5 秒内的错误突发,1m 聚合将完全掩盖该事件,导致误报或漏报。
3.2 空间聚合:分组维度与基数爆炸
空间聚合定义了指标按哪些标签(Label)进行分组。常见的分组维度包括 host、service、endpoint、status_code 等。每个维度组合都会产生一条独立的时间序列。
数据量计算公式:
总时间序列数 = 基数(维度1) × 基数(维度2) × … × 基数(维度N)
每日数据点数 = 总时间序列数 × 每日每序列点数
示例: 假设有 10 台主机、5 个服务、20 个端点、4 个状态码(2xx/4xx/5xx/其他),且全部维度组合均存在:
总时间序列数 = 10 × 5 × 20 × 4 = 4,000 条
每日数据点数(1s 窗口)= 4,000 × 86,400 ≈ 3.456 亿点
若仅按 service 聚合,则只有 5 条序列,每日数据点降至 432,000 点,减少 800 倍。
3.3 时间与空间聚合的联合影响
实际系统中,时间窗口和空间聚合同时作用。下图展示了不同聚合粒度组合下的数据量相对比例:
3.4 聚合策略选择建议
根据 SLI 的精度要求和基础设施规模,推荐以下策略:
- 高精度 SLI(如 P99 延迟、错误率突发检测): 使用 1s–10s 时间窗口,按
service+endpoint分组,避免按host或instance展开。 - 中等精度 SLI(如平均延迟、可用性): 使用 1m 时间窗口,按
service分组,必要时增加status_code维度。 - 长期趋势与容量规划: 使用 5m 或更粗窗口,仅保留
service维度,或使用降采样存储。
避坑提示: 避免将高基数标签(如
user_id、request_id、session_id)直接作为指标标签。这会导致基数爆炸,使存储和查询成本失控。应使用直方图或日志记录替代。
3.5 OpenTelemetry 中的聚合配置
在 OpenTelemetry Collector 中,可以通过 metricstransform 或 filter 处理器控制聚合粒度:
# 示例:将 1s 粒度的指标聚合为 1m 输出
processors:
metricstransform:
transforms:
- include: ^http_server_duration_ms$
match_type: regexp
action: aggregate
aggregation: mean
aggregation_interval: 60s
new_name: http_server_duration_ms_1m
# 示例:按 service 分组,丢弃 host 标签
filter:
metrics:
include:
match_type: strict
metric_names:
- http_server_duration_ms
exclude:
match_type: strict
resource_attributes:
- key: host.name
value: "*"