结论:头部采样(head sampling)在 trace 起点决定采不采(按固定比例、按限流),决策简单、成本低,但错误 trace 与慢请求可能被随机丢弃;尾部采样(tail sampling)等整条 trace 收集完再按内容决定(保留含错误的、延迟超阈值的、特定属性的),保留价值高但需要在 collector 缓存完整 trace,内存与架构复杂度高。流量大且关注异常诊断的系统应尽量尾部采样。
展开:头部采样的实现是 SDK 层 TraceIdRatioBased(如 1%)或 ParentBased(遵从上游决定,保证链路完整),配合传播 header(traceparent 的 sampled 位)全链路一致。尾部采样在 OTel Collector 的 tail_sampling processor 配置策略组合:status_code=ERROR 全留、latency > 2s 全留、其余按 5% 概率留——缺陷是"决策窗口"内 trace 必须完整到达,跨长时间段的 span 和超大 trace 有内存压力,且需要 collector 集群按 traceID 路由(load balancing exporter)保证同 trace 到同实例。折中:头部低比例采样保全景统计 + 日志侧对错误全量记录 trace_id 兜底。易错点:1)部分链路组件不传播采样位导致链路断裂;2)采样率影响基于 span 的指标统计(如用 span 算 QPS),统计类需求应走 metrics 而非 trace。
# OTel Collector 尾部采样示例
processors:
tail_sampling:
decision_wait: 10s
policies:
- { name: errors, type: status_code, status_code: { status_codes: [ERROR] } }
- { name: slow, type: latency, latency: { threshold_ms: 2000 } }
- { name: baseline, type: probabilistic, probabilistic: { sampling_percentage: 5 } }
追问方向:Jaeger 的远程采样(adaptive sampling 按服务/操作动态调比例)、采样与成本的量化模型。