3. Tempo分布式追踪概述:Tempo架构、Span与Trace模型、Tempo与OpenTelemetry的关系
3.1 为什么SRE需要理解Tempo
在SLO违约根因定位场景中,MTTR(平均修复时间)的复盘口径高度依赖分布式追踪数据的完整性与查询效率。Grafana Tempo作为专为高基数、低成本设计的分布式追踪后端,与OpenTelemetry标准深度绑定,是构建可观测性平台的核心组件。理解Tempo的架构设计、Span与Trace的数据模型,以及它与OpenTelemetry的协作关系,是优化查询性能、缩短MTTR复盘口径的前提。
核心认知: Tempo不存储应用日志或指标,只存储追踪数据(Trace)。它通过对象存储(如S3、GCS)实现低成本持久化,并通过与OpenTelemetry Collector的集成实现无厂商锁定的数据采集。
3.2 Tempo架构全景
Tempo采用微服务架构,核心组件包括Distributor、Ingester、Querier、Compactor和Query Frontend。各组件职责清晰,通过gRPC/HTTP通信,支持水平扩展。
| 组件 | 职责 | 关键特性 |
|---|---|---|
| Distributor | 接收来自OpenTelemetry Collector或其他客户端的Span数据,进行验证、采样和负载均衡 | 无状态,支持Hash环分片,将Span转发至对应的Ingester |
| Ingester | 将Span数据缓冲在内存中,并定期刷新到后端存储(对象存储) | 有状态,支持WAL(Write-Ahead Log)防止数据丢失,默认每30秒刷新一次 |
| Querier | 接收查询请求,从Ingester(热数据)和后端存储(冷数据)中检索Trace | 无状态,支持Trace ID精确查询和Service/Operation/Attributes组合查询 |
| Compactor | 合并后端存储中的小文件,减少存储碎片,提高查询效率 | 后台运行,可配置合并策略和保留周期 |
| Query Frontend | 作为查询层的入口,负责查询拆分、缓存和结果合并 | 支持查询分片、并行查询和结果缓存,显著降低查询延迟 |
MTTR复盘优化点: 在SLO违约场景中,Query Frontend的缓存机制可以加速对高频Trace ID的重复查询,建议将缓存TTL设置为与SLO评估窗口一致(如5分钟),避免冷查询拖慢复盘速度。
3.3 Span与Trace模型
Tempo的数据模型严格遵循OpenTelemetry规范。一个Trace由多个Span组成,每个Span代表分布式系统中的一次操作单元。Span之间通过SpanContext中的Trace ID和Span ID建立父子关系。
3.3.1 Span核心字段
| 字段 | 类型 | 说明 | MTTR复盘用途 |
|---|---|---|---|
| TraceId | 16字节 | 全局唯一标识一次完整请求 | 关联所有相关Span,定位全链路 |
| SpanId | 8字节 | 标识单个Span | 区分不同操作单元 |
| ParentSpanId | 8字节 | 父Span的ID,根Span为空 | 构建调用链拓扑 |
| SpanKind | 枚举 | CLIENT / SERVER / INTERNAL / PRODUCER / CONSUMER | 判断调用方向,识别上下游依赖 |
| StartTime / EndTime | 时间戳 | Span的开始和结束时间 | 计算延迟,定位慢操作 |
| Attributes | 键值对 | 自定义元数据,如HTTP方法、状态码、DB语句 | 过滤和聚合,按服务/接口/错误码分组 |
| Status | OK / ERROR / UNSET | 操作结果状态 | 快速识别失败Span,关联错误堆栈 |
| Events | 列表 | 带时间戳的日志事件,如异常抛出、缓存命中 | 补充诊断上下文 |
3.3.2 Trace树形结构
一个Trace在逻辑上构成一棵有向无环树(DAG),根Span代表入口请求(如HTTP API调用),子Span代表内部服务调用、数据库查询或消息发送。Tempo通过Trace ID聚合所有Span,并在查询时重建完整的调用链拓扑。
3.4 Tempo与OpenTelemetry的关系
Tempo与OpenTelemetry(OTel)的关系可以概括为:OTel定义标准,Tempo实现存储与查询。具体体现在以下三个层面:
- 数据协议层: Tempo原生支持通过OTLP(OpenTelemetry Protocol)接收Span数据,无需额外的协议转换器。OTel SDK和Collector可以直接将数据推送到Tempo的Distributor。
- 数据模型层: Tempo内部存储的Span结构完全对齐OTel的Span模型,包括TraceId、SpanId、Attributes、Events等字段。这意味着在OTel中定义的任何属性都可以在Tempo中直接用于查询和过滤。
- 生态集成层: Tempo与OpenTelemetry Collector深度集成,支持Collector的批量处理、采样、属性修改等预处理能力。同时,Tempo的查询语言TraceQL也兼容OTel的语义约定(Semantic Conventions),例如使用
http.status_code或db.system作为查询条件。
常见误区: Tempo不是OpenTelemetry的替代品,而是其存储后端的一种实现。OTel负责数据的生成、采集和导出,Tempo负责数据的持久化、索引和检索。两者配合使用才能构建完整的分布式追踪体系。
3.4.1 数据采集链路对比
| 环节 | OpenTelemetry | Tempo |
|---|---|---|
| 数据生成 | OTel SDK(Java/Go/Python等) | 不参与 |
| 数据采集 | OTel Collector(Agent/Gateway模式) | 不参与 |
| 数据传输 | OTLP gRPC/HTTP | 接收OTLP请求 |
| 数据存储 | 不参与 | 内存 + 对象存储 |
| 数据查询 | 不参与 | TraceQL / 服务图 |
| 数据可视化 | 不参与 | Grafana Explore / 服务图面板 |
3.5 本章小结
- Tempo采用Distributor、Ingester、Querier、Compactor、Query Frontend五组件架构,支持水平扩展和低成本对象存储。
- Span是追踪的最小单元,包含TraceId、SpanId、ParentSpanId、Attributes等关键字段;Trace由多个Span构成树形结构。
- Tempo与OpenTelemetry是互补关系:OTel负责数据生成与采集,Tempo负责存储与查询,两者通过OTLP协议无缝对接。
- 理解Tempo的架构和数据模型,是后续优化TraceQL查询、缩短MTTR复盘口径的基础。