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 哈希分片。
Grafana Tempo 核心架构 应用 / SDK Distributor Ingester 对象存储 (S3/GCS/Azure) Query Frontend Querier 组件职责说明: • Distributor:接收 Span 数据,按 Trace ID 哈希分片,转发至对应 Ingester。 • Ingester:将 Span 批量打包为 Block,写入对象存储;同时维护最近数据的内存缓存。 • Querier:从对象存储和 Ingester 内存中查找 Block,合并完整 Trace。 • Query Frontend:提供查询缓存、分片、并行化能力,降低 Querier 负载。

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 操作性能下降
多租户数据隔离流程 租户 A 应用 租户 B 应用 Distributor Ingester S3 存储桶 /tenant-a/block1 /tenant-b/block1 /tenant-a/block2 多租户隔离关键点: 1. 应用通过 HTTP 头 X-Scope-OrgID: tenant-a 标识租户。 2. Distributor 根据租户 ID 将 Span 路由到对应 Ingester 分片。 3. Ingester 写入时自动附加租户前缀,存储层物理隔离。 4. Querier 查询时只扫描对应租户前缀下的 Block,保证数据安全。

4.5 生产环境部署建议

  • 存储后端选择: 优先选择与现有云基础设施一致的后端,减少网络出口费用。GCS 的强一致性可避免偶发的 Trace 碎片问题。
  • 多租户容量规划: 每个租户建议预留独立 Ingester 内存资源,避免大租户影响小租户的写入延迟。
  • Block 生命周期: 配置 storage.trace.block.retention 控制数据保留时间,配合对象存储的生命周期策略实现冷热分层。
  • 监控指标: 重点监控 tempo_ingester_bytes_received_total 和 tempo_querier_blocks_scanned,评估存储写入和查询性能。