4. Tempo 配置基础:配置文件结构与核心配置项详解

Grafana Tempo 的配置体系围绕 tempo.yaml 单一配置文件展开,所有组件(distributor、ingester、querier、compactor)共享同一份配置,通过 target 参数决定进程启动的角色。理解配置文件的层级结构和核心配置项,是进行查询优化与索引调优的前提。

4.1 配置文件结构(tempo.yaml)

tempo.yaml 采用 YAML 格式,顶层键对应 Tempo 的架构组件和通用基础设施。以下为典型结构概览:

顶层配置块 职责说明 是否必须
server HTTP/gRPC 监听端口、TLS、日志级别 是
distributor Span 接收、负载均衡、接收器协议 是
ingester 数据写入、内存块管理、刷盘策略 是
querier 查询前端、查询并行度、TraceQL 执行 是
compactor 后端块合并、去重、 retention 清理 是
storage 后端存储引擎(S3/GCS/Azure/Local)、索引配置 是
memberlist 集群节点发现与 gossip 通信 集群模式必须
overrides 租户级配额、限流、配置覆盖 推荐
配置加载顺序:Tempo 支持通过环境变量、命令行参数覆盖 YAML 配置。生产环境建议将敏感信息(如存储密钥)通过环境变量注入,避免明文写入配置文件。

以下是一个最小化 tempo.yaml 骨架示例:

server:
  http_listen_port: 3200
  grpc_listen_port: 9095

distributor:
  receivers:
    otlp:
      protocols:
        grpc:
          endpoint: 0.0.0.0:4317

ingester:
  lifecycler:
    ring:
      kvstore:
        store: memberlist

querier:
  frontend_worker:
    frontend_address: 127.0.0.1:9095

compactor:
  compaction:
    block_retention: 336h

storage:
  trace:
    backend: s3
    s3:
      bucket: tempo-traces
      endpoint: s3.amazonaws.com
    pool:
      max_workers: 100
    block:
      bloom_filter_false_positive: 0.05
      encoding: zstd
    wal:
      path: /var/tempo/wal

4.2 核心配置项详解

4.2.1 storage 配置:索引与存储引擎

storage 是 Tempo 性能调优的核心,直接影响查询延迟和存储成本。它包含后端适配器、块索引、WAL 和缓存策略。

关键调优参数:
  • block.bloom_filter_false_positive:布隆过滤器假阳性率,默认 0.05。降低到 0.01 可减少不必要的块扫描,但会增加内存开销。
  • block.encoding:块压缩编码,推荐 zstd(压缩比高)或 snappy(速度快)。
  • block.index_downsample_bytes:索引下采样字节数,控制索引粒度,默认 1MB。增大可减少索引大小,但会降低查询精度。
  • wal.encoding:WAL 编码,建议与块编码一致,避免转换开销。

存储后端配置示例(S3):

storage:
  trace:
    backend: s3
    s3:
      bucket: tempo-traces
      endpoint: s3.us-east-1.amazonaws.com
      access_key: ${AWS_ACCESS_KEY_ID}
      secret_key: ${AWS_SECRET_ACCESS_KEY}
    block:
      bloom_filter_false_positive: 0.01
      encoding: zstd
      index_downsample_bytes: 2097152  # 2MB
    wal:
      path: /var/tempo/wal
      encoding: zstd

4.2.2 distributor 配置:数据入口与负载均衡

Distributor 负责接收来自 OpenTelemetry Collector、Jaeger Agent 等客户端的 Span 数据,并根据一致性哈希将数据路由到对应的 Ingester。

配置项 默认值 说明
receivers.otlp.protocols.grpc.endpoint 0.0.0.0:4317 OTLP gRPC 接收端点
receivers.jaeger.protocols.grpc.endpoint 0.0.0.0:14250 Jaeger gRPC 接收端点
distributor.log_received_spans false 是否记录接收到的 Span 日志(调试用,生产慎开)
distributor.extend_wal true 是否在接收时扩展 WAL,提高写入吞吐
注意:Distributor 是无状态的,可以水平扩展。但所有 Distributor 必须使用相同的 memberlist 或 consul 来发现 Ingester 实例,否则会导致数据路由不一致。

4.2.3 ingester 配置:内存块与刷盘策略

Ingester 是 Tempo 的写入路径核心,负责将 Span 数据暂存在内存中,按时间或大小切分成块(block),最终刷写到后端存储。

ingester:
  lifecycler:
    ring:
      kvstore:
        store: memberlist
      replication_factor: 3
  trace_idle_period: 10s        # 无新 Span 时,块最大等待时间
  max_block_duration: 30m       # 块最大生命周期
  max_block_bytes: 500_000_000  # 块最大字节数(500MB)
  flush_check_period: 30s       # 刷盘检查周期
  • trace_idle_period:如果某个 trace 在 10 秒内没有新 Span 到达,则关闭当前块。减小此值可加速数据可见性,但会增加块数量。
  • max_block_duration:块从创建到刷盘的最大时间,默认 30 分钟。增大可减少块数量,但会延迟数据可查询时间。
  • max_block_bytes:块大小上限,达到此值立即刷盘。建议根据 Span 平均大小和内存预算调整。

4.2.4 querier 配置:查询并行与 TraceQL 执行

Querier 负责处理来自 Query Frontend 的查询请求,扫描后端存储中的块,执行 TraceQL 过滤并返回结果。

配置项 默认值 说明
querier.search.max_duration 168h 查询最大时间范围,超过则拒绝
querier.search.query_timeout 30s 单次查询超时时间
querier.max_concurrent_queries 20 每个 Querier 实例的最大并发查询数
querier.frontend_worker.frontend_address — Query Frontend 的 gRPC 地址
优化建议:如果查询延迟高,可适当增大 max_concurrent_queries,但需监控 CPU 和内存使用。同时确保 storage.pool.max_workers 足够大,避免后端存储成为瓶颈。

4.2.5 compactor 配置:块合并与数据生命周期

Compactor 是 Tempo 的后台维护组件,负责将后端存储中的小块合并成大块,执行数据去重,并根据 retention 策略清理过期数据。

compactor:
  compaction:
    block_retention: 336h               # 数据保留时间(14天)
    compacted_block_retention: 1h       # 合并后源块保留时间
    compaction_window: 1h               # 合并时间窗口
    max_block_bytes: 1073741824         # 合并后最大块大小(1GB)
    max_compaction_objects: 1000000     # 单次合并最大对象数
  ring:
    kvstore:
      store: memberlist
  • block_retention:数据保留时长,超过此时间的块会被 Compactor 删除。支持 h(小时)、d(天)单位。
  • compaction_window:合并操作的时间窗口,默认 1 小时。窗口越小,合并越频繁,但可能产生过多小块。
  • max_block_bytes:合并后块的最大字节数。增大可减少块数量,但会延长单次合并时间。

4.3 组件协作关系图

以下 SVG 展示了 Tempo 各组件通过 tempo.yaml 配置驱动的数据流与协作关系:

Tempo 组件协作与配置映射 Tempo 组件协作与配置映射 数据源 OTLP / Jaeger Distributor 接收 / 路由 Ingester 内存块 / WAL 后端存储 S3 / GCS / 本地 Querier 查询 / TraceQL Compactor 合并 / 清理 配置映射: tempo.yaml → storage(后端/索引) | distributor(接收器) | ingester(块策略) | querier(并发/超时) | compactor(合并/retention)

4.4 配置优先级与覆盖机制

Tempo 支持多层级配置覆盖,理解优先级有助于快速定位问题:

  1. 默认值:Tempo 内置的出厂配置,适用于快速启动。
  2. tempo.yaml:主配置文件,覆盖默认值。
  3. 环境变量:以 _ 分隔的路径格式覆盖,例如 STORAGE_TRACE_BACKEND=local。
  4. 命令行参数:通过 -config.file 指定配置文件路径,或使用 -storage.trace.backend 直接覆盖。
  5. Overrides 模块:通过 overrides 配置块实现租户级覆盖,优先级最高。
常见陷阱:环境变量覆盖 YAML 配置时,如果 YAML 中存在嵌套结构,环境变量必须使用双下划线 __ 分隔层级。例如 STORAGE__TRACE__BACKEND 对应 storage.trace.backend。错误的命名会导致配置不生效。

4.5 配置验证与调试

在将配置部署到生产环境前,建议使用以下方法验证:

  • tempo -config.file=tempo.yaml -verify-config:Tempo 内置配置验证命令,检查语法和必填项。
  • tempo -config.file=tempo.yaml -print-config:打印最终生效的配置(包含所有覆盖),用于调试。
  • 日志级别调整:在 server.log_level 设置为 debug,观察启动时各组件加载的配置值。

以下 SVG 展示了配置验证与生效流程:

配置验证与生效流程 配置验证与生效流程 tempo.yaml 环境变量 命令行参数 最终配置 验证命令:tempo -config.file=tempo.yaml -verify-config | 调试命令:tempo -config.file=tempo.yaml -print-config

4.6 生产环境配置清单

以下清单总结了生产环境部署 Tempo 时,tempo.yaml 中必须关注的核心配置项:

配置路径 推荐值 说明
storage.trace.backend s3 / gcs 生产环境避免使用 local,不具备持久化能力
storage.trace.block.bloom_filter_false_positive 0.01 降低假阳性率,减少无效块扫描
storage.trace.block.encoding zstd 高压缩比,降低存储成本
ingester.max_block_bytes 500_000_000 根据内存预算调整,避免 OOM
ingester.trace_idle_period 10s 平衡数据可见性与块数量
querier.max_concurrent_queries 20 根据 CPU 核心数调整
compactor.compaction.block_retention 336h 14 天,符合大多数可观测性场景
memberlist.bind_port 7946 确保集群节点间网络互通
配置即文档:建议将 tempo.yaml 纳入版本控制,并在文件头部添加注释说明每个配置项的调整原因。这有助于团队协作和故障排查。