3. 多维度聚合基础:常见的聚合维度(服务、实例、地域、版本、用户),维度爆炸问题与数据稀疏性

在可观测性体系中,SLI(Service Level Indicator)的原始数据通常以高基数、多标签的形式存在。为了从不同视角评估服务质量,我们需要对原始指标进行多维度聚合。然而,不加约束的维度组合会引发严重的性能与存储问题。本章将系统梳理常见的聚合维度,并深入分析维度爆炸与数据稀疏性这两个核心挑战。

3.1 常见的聚合维度

在微服务与分布式系统架构中,以下五个维度是定义与聚合 SLI 时最常使用的标签键(Label Key)。每个维度都代表一个独立的故障域或观察视角。

维度 典型标签示例 基数范围 聚合目的
服务 service_name="checkout" 10 ~ 500 识别单个微服务的健康状态,区分业务边界
实例 instance_id="i-0a1b2c3d" 100 ~ 10,000+ 定位故障节点,评估负载均衡与扩缩容效果
地域 region="us-east-1" 5 ~ 50 分析多区域部署的延迟差异与可用性
版本 version="v2.3.1" 5 ~ 100 灰度发布与回滚监控,评估新版本性能回归
用户 user_id="uid_98765" 10,000 ~ 10,000,000+ 租户隔离、大客户 SLA 追踪、异常流量溯源
实践建议:在定义 SLI 的原始指标时,应优先将服务和地域作为必选标签。这两个维度通常具有明确的业务含义且基数可控,是聚合分析的起点。而用户维度基数极高,应谨慎启用,仅在需要租户级 SLA 或安全审计时使用。

3.2 维度爆炸问题

维度爆炸(Cardinality Explosion)是指当多个高基数维度组合在一起时,时间序列的数量呈指数级增长的现象。这种增长会迅速压垮指标存储后端(如 Prometheus、Thanos、M3DB),导致查询超时、存储成本飙升。

假设我们有四个维度,每个维度的基数如下:

  • 服务:50 个
  • 实例:每个服务 200 个,共 10,000 个
  • 地域:10 个
  • 版本:5 个

如果将所有维度组合为一个指标,理论上产生的时序数量为:

50 (服务) × 10,000 (实例) × 10 (地域) × 5 (版本) = 25,000,000 条时序

这仅仅是四个维度的组合。如果再加上用户维度(假设 100 万),时序数量将直接膨胀到 25 万亿,这在任何生产系统中都是不可接受的。

避坑指南:不要试图在一个指标上挂载所有可能的标签。维度爆炸的早期信号包括:Prometheus 的 Head 内存持续增长、TSDB 写入延迟飙升、查询返回结果超时。一旦发现这些信号,应立即审查指标的标签设计。

下图展示了维度组合如何从少量标签演变为时序爆炸的过程:

维度组合与时序爆炸示意图 服务 (50) 实例 (10,000) 地域 (10) 版本 (5) 维度组合 50 × 10,000 × 10 × 5 = 25,000,000 + 用户 (1,000,000) = 25,000,000,000,000 时序爆炸 存储成本激增 查询性能退化 内存/CPU 飙升 告警规则超时 仪表盘加载失败 最终:系统不可用

3.3 数据稀疏性

数据稀疏性(Data Sparsity)是与维度爆炸相伴而生的另一个问题。当维度组合过多时,绝大多数时序在大部分时间窗口内都没有新数据点写入,形成大量“空时序”。这些空时序仍然占用存储索引和内存开销,但实际承载的有效信息极少。

数据稀疏性在以下场景中尤为突出:

  • 用户维度 + 低频操作:例如“用户注册成功”指标,每个用户一生只产生一次数据点。如果按 user_id 打标签,99.9% 的时序在绝大多数时间窗口内都是空的。
  • 实例维度 + 滚动更新:在 Kubernetes 滚动更新中,旧实例被销毁、新实例被创建。已销毁的实例不再产生数据,但其对应的时序仍然保留在索引中,直到被垃圾回收。
  • 版本维度 + 灰度发布:只有少数实例运行新版本,导致新版本对应的时序数据点稀疏,而旧版本时序逐渐变空。
核心观点:维度爆炸是量的问题(时序数量过多),数据稀疏性是质的问题(时序数据密度过低)。两者共同导致存储与计算资源的浪费。优化 SLI 口径时,必须同时考虑这两个因素。

下图对比了稠密时序与稀疏时序在存储与查询上的差异:

稠密时序 vs 稀疏时序对比 稠密时序(推荐) 维度:service + region + version 基数:50 × 10 × 5 = 2,500 条时序 每个时序每分钟产生 1 个数据点 数据密度:高(100% 时间窗口有数据) ✓ 查询快速,存储可控 ✓ 聚合结果准确 稀疏时序(需避免) 维度:service + instance + user_id 基数:50 × 10,000 × 1,000,000 = 500,000,000,000 条时序 每个用户每天仅产生 1 个数据点 数据密度:极低(0.07% 时间窗口有数据) ✗ 存储爆炸,查询超时 ✗ 聚合结果不可靠

3.4 应对策略概览

针对维度爆炸与数据稀疏性,业界形成了以下成熟的应对策略。这些策略将在后续章节中详细展开:

策略 核心思想 适用场景
标签降维 移除高基数、低价值的标签,保留核心维度 所有 SLI 指标的初始设计阶段
预聚合 在写入前按指定维度计算聚合值,存储聚合结果而非原始数据 已知的固定查询模式,如服务级可用性
分层存储 原始高基数数据存短期,聚合数据存长期 需要同时支持细粒度排查与长期趋势分析
自适应采样 对稀疏时序降低采样率,对稠密时序保持全量 用户维度、Trace 数据
记录级过滤 在查询时使用正则或精确匹配过滤,避免全表扫描 临时性、偶发性的高基数查询
本章小结:多维度聚合是 SLI 口径设计的核心能力,但必须警惕维度爆炸与数据稀疏性带来的副作用。在定义指标标签时,应遵循“够用就好”的原则:优先选择基数低、业务意义明确的维度(服务、地域、版本),谨慎引入高基数维度(实例、用户)。后续章节将逐一介绍如何通过预聚合、降维和分层存储来优化 SLI 口径精度。