采样与对比:策略、Zipkin 并入与 Tempo 取舍
基于 Jaeger 1.x + OpenTelemetry · 核于 2026-08
速查
- 为什么采样:高流量场景不可能全采 trace(每请求一个,存储+处理成本爆炸),必须采样控制上报量。但采样有损——可能丢掉关键错误 trace。
- 头部采样(Head-based):在请求入口决定是否采样,被采的整条 trace 都采,被丢的整条都丢。简单、低延迟,但入口采样 1% 意味着 99% 请求连错误 trace 都没有(稀有错误可能漏)。
- 尾部采样(Tail-based):在请求结束后按条件决定是否采(如 is error? latency > 1s? has specific tag?)。精准(保证采到错误与慢请求),但要在 Collector 缓存所有 trace 到结束(内存+延迟)。
- 采样策略:①概率(probabilistic)——按固定概率(如 1%);②速率限制(ratelimiting)——每秒最多 N 个;③远程(remote)——中心化动态配置,可按服务/端点不同;④常量(const)——全采或全不采(测试用)。
- Zipkin 并入 OTel:Zipkin(Twitter 2012)是早期开源追踪,现基本并入 OTel 生态——用 OTel SDK 埋点,Zipkin 作可选后端。Jaeger 支持接收 Zipkin 格式数据(迁移友好)。新项目用 OTel SDK + Jaeger/Tempo,不建议再上 Zipkin。
- Jaeger vs Tempo:Jaeger 原生支持属性检索(按 service/operation/tags/latency 查 trace,强但存储贵);Tempo 设计相反——按 traceID 查找(不索引属性,省存储约 Jaeger 1/N),早期不支持属性检索(只能 traceID),新版 TraceQL 补齐属性检索。
- 选型:要强属性检索(不知道 traceID 时按 service/错误查)选 Jaeger;要省存储+已上 Grafana 栈选 Tempo。
一、为什么必须采样
分布式追踪的根本矛盾:每请求一个 trace,数据量 = 请求量。高流量系统(如电商秒杀、API 网关)每秒几万请求,全采 trace 的成本(存储+网络+处理)爆炸。所以必须采样——只保留一部分 trace。但采样有损:
- 错误可能漏采:如果采样率 1%,恰好那个 500 错误的请求被丢,就完全没有它的 trace,排障无据。
- 慢请求可能漏采:同理,慢请求稀有,1% 采样可能恰好错过。
- 尾部采样的价值:等请求结束再决定,保证采到错误/慢请求。
二、头部采样 vs 尾部采样
头部采样(Head-based,入口决定)
请求到 gateway → gateway 决定是否采样(按概率 1% 或速率)
→ 采样的请求:traceID 标记 sampled=1,整条 trace 所有 span 都采
→ 不采样的请求:所有 span 都不采(最终不导出到后端)- 优点:简单、低延迟(入口决定,无需缓存)、SDK 端实现。
- 缺点:入口采样 1% 意味着 99% 请求(包括错误/慢请求)无 trace——稀有错误可能漏。
尾部采样(Tail-based,结束决定)
所有请求的 span 都先发到 OTel Collector,Collector 缓存
→ 请求结束(trace 完整)
→ Collector 按条件判断:
- is error?(error=true)→ 采
- latency > 1s?(慢请求)→ 采
- has tag X?(特定属性)→ 采
- 其他 → 按低概率采(如 0.1%)
→ 被采的导出到后端,其他丢弃- 优点:精准——保证采到所有错误、所有慢请求,稀有错误不漏。
- 缺点:①要在 Collector 缓存所有 trace 到请求结束(内存开销);②延迟(必须等结束);③Collector 复杂度增加。
- 实现:OTel Collector 的 tail_sampling processor,配置策略组合。
选型
- 头部采样:流量均匀、错误率稳定、预算敏感——简单够用。
- 尾部采样:错误稀有但关键、慢请求难复现、要保证采到关键 trace——值得复杂度。
三、采样策略详解
| 策略 | 配置 | 适用 |
|---|---|---|
| const | samplingProbability: 0 或 1(全不采/全采) | 测试/调试 |
| probabilistic | samplingProbability: 0.01(1%) | 流量均匀,预算敏感 |
| ratelimiting | maxTracesPerSecond: 10 | 平滑流量,突发流量保护 |
| remote | 中心化配置,动态调整 | 生产推荐,可按服务/端点不同 |
| tail sampling(在 Collector) | 按条件(error/latency/tag) | 精准,保证采到关键 trace |
远程采样(生产推荐)
yaml
# Jaeger 远程采样配置
sampling:
strategies:
- service: api-gateway
type: probabilistic
param: 0.5 # 网关 50%
- service: payment-svc
type: ratelimiting
param: 100 # 支付服务 100 traces/s(关键服务多采)- 动态调整:不用重启服务,改中心配置即生效。
- 按服务/端点:关键服务(支付)高采样,普通服务低采样。
四、Zipkin:并入 OTel 生态
Zipkin 是 Twitter 2012 开源的早期分布式追踪系统:
- 历史地位:最早的成熟开源追踪系统,普及了 trace/span 模型。
- 现状:基本被 OTel + Jaeger/Tempo 取代——OTel SDK 厂商中立,Zipkin 作为可选后端存在。
- Jaeger 兼容 Zipkin:Jaeger Collector 可接收 Zipkin 格式数据(
/api/v1/spans端点),从 Zipkin 迁移到 Jaeger 无需改业务代码。 - 新项目建议:直接用 OTel SDK + Jaeger/Tempo,不上 Zipkin(Zipkin 维护活跃度低于 OTel 生态)。
五、Jaeger vs Tempo:检索与存储的取舍
Jaeger 和 Tempo(Grafana 系)都是 OTel trace 后端,但设计哲学相反:
| 维度 | Jaeger | Tempo |
|---|---|---|
| 索引模型 | 索引属性(service/operation/tags) | 只索引 traceID(不索引属性) |
| 属性检索 | 强(按 service/错误/latency 查) | 弱(早期只能 traceID,新版 TraceQL 补齐) |
| 按 traceID 查 | 支持 | 核心设计(高效) |
| 存储成本 | 高(索引属性) | 低(不索引属性,约省 N 倍) |
| 生态 | CNCF / Uber | Grafana LGTM |
| 可视化 | 自带 UI | Grafana |
Jaeger 的属性检索价值
场景:用户报「下单偶发失败」,但你不知道 traceID
Jaeger 查询:service=order-svc AND operation=POST /api/order AND tags.error=true
→ 返回所有出错的下单 trace,定位根因- 不知道 traceID 时:按属性查(service/operation/tags)找到问题 trace。
- 代价:要索引所有属性,存储与索引成本高。
Tempo 的 traceID 查找价值
场景:从指标/Sentry 拿到 traceID(Exemplar/error event 带 traceID)
Tempo 查询:GET /api/traces/<traceID>
→ 直接返回该 trace(高效,因不索引属性省存储)- 配合 LGTM 联动:从 Grafana 指标 Exemplar → Tempo trace → Loki 日志,traceID 贯穿。
- 代价:不知道 traceID 时难找问题(早期),新版 TraceQL 补齐属性检索但仍弱于 Jaeger。
选型决策
- 选 Jaeger:①需要强属性检索(按 service/operation/tags 查);②不知道 traceID 时要找问题 trace;③CNCF 生态、Uber 出品信任度高;④预算能承担存储成本。
- 选 Tempo:①已上 Grafana 栈,要 traceID 四支柱联动;②存储成本敏感(Tempo 省 N 倍);③查询模式是「先拿到 traceID 再查」(配合指标 Exemplar)。
- 两者都支持 OTel:埋点一次,后端可切换/并存。
六、典型集成:OTel + Jaeger 全链路
应用(OTel SDK 埋点)
→ OTLP 导出
→ OTel Collector(可选,做 batch + tail sampling)
→ Jaeger Collector
→ Storage(Cassandra/ES)
→ Jaeger UI(瀑布图查 trace)
配合:
- Prometheus 指标(P99 突增)
- Sentry 错误(带 traceID)
- ELK/Loki 日志(按 traceID 关联)
→ 一个请求从指标→追踪→日志→错误全链路可追溯下一步
掌握了采样策略与 Zipkin/Tempo 对比后,可看本叶参考(OTel SDK 集成速查、span 属性、采样配置、易错点),或横向看其他可观测性工具——Prometheus(指标)、Grafana(可视化)、ELK(日志)、Sentry(错误)。