采样策略总览:Head Sampling vs Tail Sampling,确定性采样 vs 概率采样,常见采样场景

采样是分布式可观测性中控制数据量、降低存储成本与网络开销的核心手段。在 OpenTelemetry 生态中,采样策略主要从两个维度进行划分:采样发生的时间点(Head vs Tail)和采样决策的确定性(确定性 vs 概率)。理解这两个维度的交叉组合,是设计生产级采样方案的基础。

核心观点:没有一种采样策略适用于所有场景。Head Sampling 适合低延迟、高吞吐的轻量决策;Tail Sampling 适合需要完整业务上下文的高精度决策。确定性采样保证可重复性,概率采样控制整体比例。

1. 采样时间点:Head Sampling vs Tail Sampling

根据采样决策发生在 Span 生命周期的哪个阶段,分为 Head Sampling(头部采样)和 Tail Sampling(尾部采样)。

对比维度 Head Sampling(头部采样) Tail Sampling(尾部采样)
决策时机 Span 创建时(SDK 侧),数据尚未离开应用进程 Span 完成并汇聚后(Collector 侧),数据已到达后端
决策依据 仅基于当前 Span 的局部属性(如 Span 名称、随机数) 基于完整 Trace 的全局信息(如错误状态、延迟、属性组合)
延迟影响 极低(微秒级),无额外网络开销 较高(毫秒级),需要缓冲等待 Trace 完整
资源消耗 低,仅占用 SDK 侧少量 CPU 高,Collector 需要维护 Trace 状态缓冲区
典型实现 OTel SDK 内置 Sampler(如 ParentBased、TraceIdRatio) OTel Collector 的 tail_sampling 处理器
适用场景 高流量、低延迟要求的通用采样 需要保留完整错误/慢 Trace 的精细化采样
选型建议:如果业务对延迟极度敏感(如金融交易链路),优先使用 Head Sampling;如果需要保证所有错误 Trace 都被完整保留,必须引入 Tail Sampling。生产环境中常将两者结合:Head Sampling 做第一层降量,Tail Sampling 做第二层精准筛选。
Head Sampling vs Tail Sampling 流程对比 Head Sampling(SDK 侧) 应用进程创建 Span SDK Sampler 决策 采样(保留) 丢弃 发送到 Collector Tail Sampling(Collector 侧) 所有 Span 发送到 Collector 缓冲等待 Trace 完整 基于全局策略决策 保留完整 Trace 丢弃

2. 决策确定性:确定性采样 vs 概率采样

根据给定输入是否总是产生相同的采样结果,分为确定性采样和概率采样。

对比维度 确定性采样 概率采样
决策规则 基于 Span/Trace 的稳定属性(如 Trace ID 哈希、Span 名称) 基于随机数生成器,每次独立
可重复性 相同输入始终得到相同结果 相同输入可能得到不同结果
一致性保证 同一 Trace 的所有 Span 采样决策一致(通过 Trace ID 哈希) 需要额外机制(如 ParentBased)保证 Trace 内一致性
典型实现 TraceIdRatioBased(基于 Trace ID 哈希取模) 简单随机采样(每个 Span 独立抛硬币)
优势 可预测、可调试、保证 Trace 完整性 实现简单、统计无偏
劣势 可能引入采样偏差(如某些 Trace ID 范围被系统性保留或丢弃) 无法保证 Trace 内一致性,可能导致部分 Span 丢失
重要提醒:在生产环境中,永远不要使用纯概率采样(每个 Span 独立随机)。这会导致同一个 Trace 的部分 Span 被采样、部分被丢弃,破坏 Trace 的完整性,使链路追踪失去意义。OpenTelemetry SDK 默认的 ParentBased 采样器就是为了解决这个问题——子 Span 继承父 Span 的采样决策。

3. 常见采样场景与策略组合

实际生产环境中,通常需要根据业务场景组合多种采样策略。以下是 6 种典型场景及其推荐策略。

场景 推荐策略 说明
高流量通用采样 Head + 确定性(TraceIdRatio) 按 Trace ID 哈希比例采样,保证 Trace 完整性,延迟最低
错误/异常全量保留 Tail + 确定性(基于状态码/属性) Collector 侧判断 Span 状态为 ERROR 时强制保留整个 Trace
慢 Trace 诊断 Tail + 确定性(基于延迟阈值) 保留超过 P99 延迟的 Trace,用于性能瓶颈分析
金丝雀/灰度发布 Head + 确定性(基于服务版本/标签) 只采样特定版本服务的 Trace,用于新版本质量验证
成本敏感型降量 Head + 概率(低比例) 如 1% 随机采样,配合 ParentBased 保证 Trace 内一致
全量采样 + 动态降级 Head(全量)→ Tail(动态降量) 先全量采集,Collector 侧根据负载动态调整采样率
最佳实践:推荐采用“分层采样”架构——第一层在 SDK 侧使用 Head Sampling 做粗粒度降量(如 10%),第二层在 Collector 侧使用 Tail Sampling 做细粒度保留(如错误 Trace 全量、慢 Trace 全量)。这样既控制了整体数据量,又保证了关键 Trace 不丢失。
采样策略决策树 采样策略选择 Head Sampling Tail Sampling TraceIdRatio ParentBased 错误状态保留 延迟阈值保留 高流量通用 (降量保完整) 成本敏感 (低比例采样) 错误全量保留 (诊断分析) 慢 Trace 诊断 (性能瓶颈) 决策原则 高流量 → Head + 确定性;关键诊断 → Tail + 确定性;成本优先 → Head + 概率

4. 采样策略组合矩阵

将时间点维度和确定性维度交叉,可以得到四种基本策略组合,每种组合都有其适用场景和注意事项。

组合 实现方式 优势 劣势 典型场景
Head + 确定性 TraceIdRatioBased Sampler 低延迟、Trace 完整、可预测 无法基于运行时状态调整 通用降量、金丝雀发布
Head + 概率 ParentBased + 随机采样 实现简单、统计无偏 无法保证 Trace 内一致(需 ParentBased 辅助) 成本敏感、低优先级数据
Tail + 确定性 tail_sampling 处理器 + 策略规则 基于完整上下文、精准保留 高延迟、高资源消耗 错误诊断、慢 Trace 分析
Tail + 概率 tail_sampling + 随机策略 可动态调整比例 可能丢失关键 Trace 极少使用,仅作为兜底
实战建议:在配置 OpenTelemetry Collector 的 tail_sampling 处理器时,建议将确定性策略(如 status_code、latency)放在策略列表前面,概率策略放在最后作为兜底。这样可以确保关键 Trace 优先被保留,剩余配额再用于随机采样。

5. 采样策略配置示例(YAML)

以下是一个结合 Head Sampling 和 Tail Sampling 的典型配置示例,展示了如何在 SDK 和 Collector 侧分别配置采样策略。

# SDK 侧:Head Sampling 配置(Java/Python/Go SDK 通用思路)
# 使用 TraceIdRatioBased 采样器,采样率 10%
otel:
  traces:
    sampler: "traceidratio"
    sampler.arg: "0.1"

# Collector 侧:Tail Sampling 配置
receivers:
  otlp:
    protocols:
      grpc:
        endpoint: 0.0.0.0:4317

processors:
  tail_sampling:
    decision_wait: 30s          # 等待 Trace 完整的最长时间
    num_traces: 100000          # 缓冲区大小
    expected_new_traces_per_sec: 1000

    policies:
      # 策略 1:错误 Trace 全量保留(确定性)
      - name: error-policy
        type: status_code
        config:
          status_codes:
            - ERROR

      # 策略 2:慢 Trace 保留(确定性,延迟 > 2s)
      - name: slow-policy
        type: latency
        config:
          threshold_ms: 2000

      # 策略 3:兜底概率采样(概率,保留 5% 的正常 Trace)
      - name: probabilistic-policy
        type: probabilistic
        config:
          sampling_percentage: 5

exporters:
  otlp:
    endpoint: your-backend:4317

service:
  pipelines:
    traces:
      receivers: [otlp]
      processors: [tail_sampling]
      exporters: [otlp]
配置陷阱:tail_sampling 的 decision_wait 参数设置过短会导致 Trace 未完整到达就被决策,造成部分 Span 丢失;设置过长会增加 Collector 内存压力。建议根据业务 Trace 的最大跨度时间(通常 5-30 秒)来设置。同时,num_traces 要根据每秒新 Trace 数 × decision_wait 来估算,避免缓冲区溢出。

6. 采样策略选型速查表

以下速查表帮助你在不同业务需求下快速选择采样策略组合。

业务需求 推荐策略 采样率参考 关键配置参数
降低存储成本 Head + TraceIdRatio 1% - 10% sampler.arg
保证错误 Trace 不丢失 Tail + status_code 错误 100%,正常 0% status_codes: [ERROR]
分析 P99 延迟 Tail + latency 慢 Trace 100% threshold_ms
新版本质量验证 Head + 属性匹配 特定版本 100% 基于 service.version 属性
全量 + 动态降级 Head 全量 → Tail 动态 根据 Collector 负载动态调整 num_traces + decision_wait
合规审计 Tail + 属性匹配 特定用户/交易 100% 基于 user_id / transaction_id 属性

采样策略的选择不是一次性的,需要根据数据量变化、业务需求演进和成本预算持续调整。建议在 Collector 侧添加采样指标监控(如采样率、丢弃率、缓冲区使用率),以便及时发现策略偏差并进行调优。