4. Grafana Tempo:Tempo架构设计、分布式存储后端(S3/GCS/Azure)、多租户模式
Grafana Tempo 是一款高性价比、高可用的分布式追踪后端,专为云原生环境设计。其核心设计哲学是“对象存储优先”与“Trace ID 索引”,通过将追踪数据直接写入廉价的对象存储(S3、GCS、Azure Blob),大幅降低运维复杂度和存储成本。本章深入解析 Tempo 的架构组件、存储后端选型以及多租户隔离机制。
4.1 整体架构与核心组件
Tempo 采用微服务架构,各组件可独立扩展。数据流从接收器(Distributor)开始,经过 Ingester 写入后端存储,最终由 Querier 和 Query Frontend 响应查询请求。
架构核心原则: 写入路径无状态,查询路径依赖 Trace ID 哈希分片。
4.2 分布式存储后端:S3 / GCS / Azure Blob
Tempo 将追踪数据持久化在对象存储中,支持以下三种主流后端。选择依据主要考虑已有基础设施、网络延迟和成本模型。
| 特性 | AWS S3 | GCP GCS | Azure Blob |
|---|---|---|---|
| 认证方式 | Access Key + Secret Key / IAM Role | Service Account JSON Key | Storage Account Key / Managed Identity |
| 存储层级 | Standard / Infrequent Access / Glacier | Standard / Nearline / Coldline / Archive | Hot / Cool / Archive |
| 数据一致性 | 最终一致性(List 操作) | 强一致性 | 最终一致性 |
| 推荐场景 | AWS 原生环境,已有 S3 数据湖 | GCP 环境,需要强一致性 | Azure 环境,与 AD 集成 |
| Tempo 配置前缀 | s3://bucket/path |
gcs://bucket/path |
azure://container/path |
存储成本优化建议: 对于超过 24 小时的旧数据,可配置生命周期策略自动迁移至低成本存储层(如 S3 Infrequent Access 或 GCS Nearline),Tempo 查询时仍可透明读取。
4.3 多租户模式
Tempo 通过 租户 ID(Tenant ID) 实现数据隔离。每个 Span 在写入时必须携带租户标识,查询时也需指定对应租户。多租户模式分为两种部署形态:
- 单租户模式: 默认模式,所有数据共享同一存储空间,适用于单一团队或小型集群。
- 多租户模式: 通过配置
multitenancy.enabled=true开启。每个租户拥有独立的存储前缀和查询范围。
4.3.1 租户数据隔离机制
数据隔离在存储层和查询层同时生效:
| 层级 | 隔离方式 | 说明 |
|---|---|---|
| 存储层 | 对象存储前缀 | 每个租户的数据存储在独立路径下,如 tempo/tenant-a/... 和 tempo/tenant-b/... |
| Ingester 层 | 内存分片 | Ingester 按租户 ID 维护独立的 Block 队列,防止数据交叉 |
| 查询层 | 请求头认证 | Querier 根据 HTTP 头 X-Scope-OrgID 过滤数据,无权限租户无法跨租户查询 |
4.3.2 多租户配置示例
# tempo.yaml 多租户配置片段
multitenancy:
enabled: true
distributor:
receivers:
otlp:
protocols:
grpc:
endpoint: 0.0.0.0:4317
ingester:
lifecycler:
ring:
kvstore:
store: memberlist
storage:
trace:
backend: s3
s3:
bucket: tempo-traces
endpoint: s3.amazonaws.com
access_key: ${AWS_ACCESS_KEY}
secret_key: ${AWS_SECRET_KEY}
# 每个租户自动使用独立前缀
# 例如:tempo-traces/tenant-a/ 和 tempo-traces/tenant-b/
注意: 开启多租户后,Grafana 数据源配置中必须设置 Custom HTTP Headers,添加
X-Scope-OrgID 为对应租户 ID,否则查询会返回空结果。
4.4 架构设计要点总结
下表归纳了 Tempo 架构中几个关键设计决策及其影响:
| 设计决策 | 优势 | 注意事项 |
|---|---|---|
| 对象存储作为唯一持久层 | 无状态写入,弹性扩展,存储成本低 | 查询延迟受对象存储 API 延迟影响 |
| Trace ID 哈希分片 | 同一 Trace 的所有 Span 路由到同一 Ingester | Ingester 重启后需从存储重建内存缓存 |
| Block 格式(Parquet / Proto) | 支持列式扫描,加速 Trace 查询 | Parquet 格式占用更多 CPU 但查询更快 |
| 多租户前缀隔离 | 无需额外数据库,存储层原生隔离 | 租户数量过多时,List 操作性能下降 |
4.5 生产环境部署建议
- 存储后端选择: 优先选择与现有云基础设施一致的后端,减少网络出口费用。GCS 的强一致性可避免偶发的 Trace 碎片问题。
- 多租户容量规划: 每个租户建议预留独立 Ingester 内存资源,避免大租户影响小租户的写入延迟。
- Block 生命周期: 配置
storage.trace.block.retention控制数据保留时间,配合对象存储的生命周期策略实现冷热分层。 - 监控指标: 重点监控
tempo_ingester_bytes_received_total和tempo_querier_blocks_scanned,评估存储写入和查询性能。