Dapper 论文精读:Google 分布式追踪系统的设计取舍
// 目录 · contents
Dapper 是 Google 2010 年发表的一篇关于分布式追踪系统的论文,全名《Dapper, a Large-Scale Distributed Systems Tracing Infrastructure》。这篇论文不长,但信息密度很高,后来 Twitter 的 Zipkin、Uber 的 Jaeger 都直接受它影响。我在团队引入 Jaeger 之前认真读了一遍,做一些记录。
为什么需要分布式追踪?
论文开头说的很直白:现代互联网服务的一个请求可能经过数百个微服务,任何一个环节出问题都可能影响用户体验,但传统的日志和指标监控很难回答”这个慢请求慢在哪里”这个问题。
举个实际场景:用户投诉某个接口偶发超时,你看指标发现 P99 确实高,但 P50 正常。日志里有几百条信息但关联不起来。这时候如果有追踪系统,可以直接找到某次超时请求的完整链路,看出是下游哪个服务耗时异常。这是 Dapper 要解决的核心问题。
核心数据模型:Trace Tree
Dapper 的数据模型很简洁:
- Trace:一次完整的请求链路,由全局唯一的 TraceId 标识
- Span:链路中的一个操作单元,有开始时间和持续时间
- Annotation:Span 上打的时间戳标记,如
cs(client send)、cr(client receive)、ss(server send)、sr(server receive)
1 | |
每个 Span 通过 SpanId + ParentSpanId 组成树结构,还原出请求的调用关系和时序。
三个关键设计目标
论文花了大量篇幅讨论三个目标,以及为了满足这些目标做出的具体取舍。
1. 低开销(Low Overhead)
Google 的要求是性能损耗小到开发者不需要关心追踪开关。为此 Dapper 用了两个手段:
异步写入:Span 数据不走请求链路,单独由后台线程写入本地日志,再由 Dapper Daemon 异步上报到中央存储。这样即使追踪系统本身出了问题,也不影响业务。
采样(Sampling):这是核心权衡。全量追踪开销太大,Dapper 默认只采样 1/1024 的请求。论文里有个关键论断:高流量服务下,1/1024 的采样率已经足够发现大多数性能问题,因为慢请求的比例相对稳定,采样后依然能捕捉到。
采样还有个细节:采样决定在 trace 的入口(第一个 Span)就做出,然后通过上下文传播到所有下游。这样保证一条 trace 要么被完整采样,要么完全不采。不然会出现一条 trace 只有部分 Span 的情况,没有分析价值。
2. 对应用透明(Application-Level Transparency)
开发者不需要手动埋点,追踪逻辑封装在公共 RPC 库里,新服务接入只需要用标准的 RPC 库。
这一点在 Google 内部做得到,是因为他们控制了底层 RPC 框架。在实际落地时,如果团队用了多种 RPC 框架(gRPC、HTTP、消息队列),每种都需要单独的 instrumentation,透明度就没那么高了。
Jaeger 和 OpenTelemetry 后来的解法是通过 Java Agent 做字节码插桩,自动拦截常用框架(Dubbo、HttpClient、MySQL 驱动等),效果接近透明。
3. 可扩展性
Dapper 的存储用的是 Bigtable,按 TraceId 分区,每条 trace 数据保存两周。查询时按 TraceId 或者特定维度(服务名、接口名、耗时范围)检索。
论文提到他们每天收集约 1TB 的采样追踪数据,存储约 8 万亿个 Span。这个量级解释了为什么采样率和存储设计要这么精细。
从论文到实际落地
读完论文之后,我们选了 Jaeger(而不是 Zipkin)作为追踪系统,原因是: - Jaeger 是 Go 写的,资源占用小 - 原生支持 Cassandra 和 Elasticsearch 作为存储后端 - 对 Kubernetes 支持更好
接入过程中遇到的最大问题不是技术的,而是采样率配置。
我们最开始把采样率设成了 100%(全量),结果 Jaeger 的 Collector 被打爆了,写入 Elasticsearch 的速度跟不上请求量,然后 Span 数据开始大量丢失。更糟糕的是,这个丢失是静默的,界面上 trace 还能查到,但很多 trace 缺少中间的 Span。
后来改为头部采样(1%)+ 对错误请求强制采样,正常查的时候 trace 完整了,出问题的请求也基本能抓到。这个策略和 Dapper 论文里描述的基本一致。
还有一个实践经验:追踪系统的价值在使用频率上。工具搭好之后,得推动团队在排查问题时真的去用它。我们起初遇到问题还是习惯先看日志,后来规定排查慢接口问题必须先拿追踪图看一眼,慢慢大家才真正用起来。
论文原文
Dapper, a Large-Scale Distributed Systems Tracing Infrastructure
推荐直接读原文,不长,大概 30 页,核心内容在第 2、3、4 节。