采样率直接决定追踪系统的成本和覆盖率。本文对比头部采样、尾部采样、动态采样三种策略的原理与取舍,给出按服务类型和流量特征选择采样率的具体建议,并附 OpenTelemetry 配置示例。
采样率是链路追踪里最容易被忽视、又最直接反映在账单上的配置。全量采集 100% 的 trace,存储和检索成本成倍增长;采样率压到 1%,又会在排查线上慢请求时漏掉关键样本。到底该用哪种采样策略?这篇文章把三种主流方案讲清楚。
头部采样在请求进入服务的那一刻就做决定,通常按固定比例随机抽取。OpenTelemetry SDK 里最常用的 TraceIdRatioBased 就是这一类:
sampler:
parentbased_traceidratio:
root:
traceidratio: 0.1
它的优点是实现简单、成本可精确预估:不管流量怎么涨,采集量永远是总量的固定百分比。但随机不等于有用——慢请求、报错请求被抽中的概率和普通请求完全一样。一次偶发的 30 秒超时,可能恰恰因为没被采样,事后想查调用链时什么都看不到。
尾部采样把采样决定推迟到请求结束之后。Collector 先把整条 trace 的 span 缓存在内存里,等 span 到齐,再根据状态码、耗时、是否报错决定保留还是丢弃:
processors:
tail_sampling:
policies:
- name: keep-errors
type: status_code
status_code: [ERROR]
- name: keep-slow
type: latency
latency: { threshold_ms: 1000 }
- name: default
type: probabilistic
sampling_percentage: 5
这样配置后,所有报错、耗时超过 1 秒的请求都会被完整保留,其余按 5% 抽样。代价是 Collector 需要维护一段时间的 span 缓存(通常 10 到 30 秒),内存占用和 Collector 集群规模要随之扩大,而且高基数场景下缓存可能被刷爆,务必给缓存设置上限。
动态采样根据实时流量和错误率调整采样率:低峰期拉高采样率,高峰期降低。炬鲸 OBSERVE 支持按 service 维度配置采样率,并在错误率突增时自动切换成全量采集,保证故障窗口内一条 trace 都不丢。它适合流量有明显波峰波谷、又不想为尾部采样额外投入 Collector 机器的场景。
最后提醒一句:采样策略要和日志、指标配合着用。trace 被采样丢弃了没关系,但日志里必须保留 traceId,这样排障时才能从一条日志反查到关联的请求上下文,而不至于彻底失去线索。