可观测性成本与采样策略
Stripe 在 2020 年的一篇技术博客中分享了一组数据:他们每天产生 800TB 的可观测性数据,年度存储成本达到数百万美元。这不是个例——随着微服务数量增长,可观测性数据的增速往往超过业务增速。
可观测性数据的成本主要有三部分:采集成本(Agent/CPU)、传输成本(网络带宽)、存储成本(磁盘/云存储)。这三部分都与数据量成正比,而数据量由采样率、服务数量、Span 复杂度共同决定。
本文的核心问题是:如何在保证可观测性的同时,控制数据成本?
成本来源分析
指标成本
指标的成本相对可控,因为它已经是聚合数据:
- 单个指标(带标签):约 1-10 KB/天(取决于时间序列数量)
- Prometheus 存储空间:压缩后约每指标每天 0.1-1 KB
指标的成本主要来自时间序列数量(Cardinality),而不是数据量。
链路追踪成本
链路追踪的成本最高,因为每个请求都会产生一条完整的 Trace:
链路追踪的成本来自:QPS × 每请求 Span 数 × 采样率。
日志成本
日志成本最高,因为日志是未经聚合的原始数据:
采样策略
采样是控制成本的核心手段。但采样也意味着放弃部分数据的可见性。采样策略的核心是:对绝大多数请求采集少量数据,对问题请求采集完整数据。
采样类型对比
头部采样实现
OTel SDK 的头部采样配置:
application.yml
尾部采样实现
尾部采样需要在 OTel Collector 层实现,因为它需要等待请求完成:
otel-collector-config.yaml
自适应采样
自适应采样的核心思想:QPS 高时降低采样率,QPS 低时提高采样率:
AdaptiveSampler.java
日志采样策略
日志的采样比链路追踪更复杂,因为日志不是请求级别的——你需要决定采样哪条日志,而不是哪个请求。
基于错误的采样
logback-spring.xml
基于百分比的采样
SamplingRateFilter.java
智能日志采样
只采样能代表整体分布的日志,而非随机丢弃:
loki-sampling.py
成本控制最佳实践
实践一:标签基数控制
prometheus.yml
实践二:数据过期策略
prometheus.yml
实践三:多级存储
thanos.yml
质量判断标准
读完本节后,你应该能够回答:
- 可观测性数据的三种主要成本来源是什么?哪种成本最高?
- 头部采样(Head-based)和尾部采样(Tail-based)的核心区别是什么?为什么尾部采样能保留更多有价值的请求?
- 链路追踪的自适应采样是如何工作的?QPS 高低与采样率的关系是什么?
- 日志采样相比链路追踪采样更复杂的原因是什么?基于错误的采样和基于百分比的采样分别适用什么场景?
- 标签基数(Cardinality)为什么是指标成本的核心问题?如何控制高基数标签?