Grafana Tempo 部署模式详解:单体(Monolithic)与微服务(Microservices)模式的选择与实战

发布时间:2026/9/18 17:14:54
Grafana Tempo 部署模式详解:单体(Monolithic)与微服务(Microservices)模式的选择与实战 Grafana Tempo 部署模式详解单体Monolithic与微服务Microservices模式的选择与实战【免费下载链接】tempoGrafana Tempo is a high volume, minimal dependency distributed tracing backend.项目地址: https://gitcode.com/GitHub_Trending/tempo1/tempoGrafana Tempo 是一个高吞吐、低依赖的分布式链路追踪后端其所有组件编译进同一个二进制文件中通过-target标志决定以哪种模式运行单体模式monolithic默认或微服务模式microservices。本文以 Deployment modes 为骨架结合 modules.go 等源码实现与仓库中的 docker-compose 示例系统讲解两种模式的架构差异、适用场景、取舍权衡与配置实战帮助你为不同规模的追踪数据量选择正确的部署形态。概述一个二进制两种模式Tempo 将所有组件编译为单一二进制文件模式的选择完全由-target标志驱动。在源码 cmd/tempo/app/config.go 中可以看到target的默认值被设置为SingleBinary即字符串allc.Target SingleBinary // ... f.StringVar(c.Target, target, SingleBinary, target module)在 cmd/tempo/app/modules.go 中Tempo 定义了全部可用的 target 取值工具类模块server、store、memberlist-kv、overrides、cache-provider等内部模块通常不直接作为 target独立组件 targetdistributor、metrics-generator、querier、query-frontend、block-builder、backend-scheduler、backend-worker、live-store复合 targetall即单体模式SingleBinaryIsSingleBinary(target)函数modules.go正是判断当前是否运行在单体模式的核心开关后续大量初始化逻辑都围绕它分叉。单体模式Monolithic mode在单体模式下所需组件在单个进程中运行使用-targetall这也是默认值。无需 Kafkadistributor 将 trace 数据进程内直接推送给 live-store 与 metrics-generatortrace 再被 flush 到配置的存储后端。生产环境建议使用对象存储object storage。从源码可以清楚地看到这一进程内推送的实现。在 modules.go 的initDistributor中singleBinary : IsSingleBinary(t.cfg.Target) localPushTargets : distributor.LocalPushTargets{} var partitionRing ring.PartitionRingReader t.cfg.Distributor.PushSpansToKafka !singleBinary if singleBinary { localPushTargets.Generator func(ctx context.Context, req *tempopb.PushSpansRequest) (*tempopb.PushResponse, error) { if t.generator nil { return nil, errors.New(metrics-generator not initialized) } return t.generator.PushSpans(ctx, req) } localPushTargets.LiveStore func(ctx context.Context, req *tempopb.PushBytesRequest) (*tempopb.PushResponse, error) { if t.liveStore nil { return nil, errors.New(live-store not initialized) } return t.liveStore.PushBytes(ctx, req) } } else { t.cfg.Distributor.KafkaConfig t.cfg.Ingest.Kafka partitionRing t.partitionRing }同理configureGenerator()modules.go设置了ConsumeFromKafka !IsSingleBinary(...)initLiveStoremodules.go也明确注释在单二进制模式下 trace 由 distributor 进程内推送live-store 不直接从 Kafka 消费。也就是说单体模式完全绕开 Kafka数据链路为distributor →进程内→ live-store / metrics-generator → flush 到存储后端。单体模式适用场景刚开始接触 Tempo 或正在评估其能力需要开发或测试环境链路数据量低于25-35 MB/s 或 55k-80k spans/s相比独立扩缩容更看重运维简单性单体模式的权衡取舍单体模式存在一些需要注意的 trade-off共享资源池所有组件共享同一份计算资源查询负载的尖峰可能影响写入吞吐反之亦然无法独立扩缩容只能垂直扩容不能对单个组件单独扩缩不支持多实例高可用由于 backend-scheduler后端调度器是单例运行多个-targetall实例是不被支持的需要高可用时应改用微服务模式内存压力在高数据量下多个组件在同一个进程内共置会带来内存压力问题这一单例限制在源码中亦有体现模块依赖 DAG 中BackendScheduler作为独立模块注册modules.go而 size.md 中 backend-scheduler 的规模建议也明确1 replica同一时间只应运行一个 scheduler。单体模式配置示例仓库中提供了开箱即用的单二进制 docker-compose 示例 example/docker-compose/single-binary其 tempo.yaml 是单体模式的典型配置stream_over_http_enabled: true server: http_listen_port: 3200 log_level: info distributor: receivers: otlp: protocols: grpc: endpoint: tempo:4317 http: endpoint: tempo:4318 metrics_generator: registry: external_labels: source: tempo cluster: docker-compose storage: path: /var/tempo/generator/wal remote_write: - url: http://prometheus:9090/api/v1/write send_exemplars: true storage: trace: backend: local wal: path: /var/tempo/wal # where to store the wal locally local: path: /var/tempo/blocks overrides: defaults: metrics_generator: processors: [span-metrics, service-graphs] generate_native_histograms: both注意该示例中storage.trace.backend: local仅适用于本地开发验证正如原文档强调的生产环境应使用对象存储S3、GCS 或 Azure Blob。当非单体模式下仍使用 local 后端时Tempo 配置检查会给出警告Local backend will not correctly retrieve traces with a distributed deployment unless all components have access to the same disk. You should probably be using object storage as a backend.见 config.go。微服务模式Microservices mode在微服务模式下每个组件作为独立进程运行各自指定自己的-target例如-targetdistributor或-targetquerier。该模式必须依赖 Kafka 兼容系统如 Apache Kafka、Redpanda 或 WarpStream作为 distributor 与下游消费者之间的持久化队列。从模块依赖 DAGmodules.go可以还原出微服务模式下各组件之间的关系liveStoreDeps : []string{Common, MemberlistKV, PartitionRing} distributorDeps : []string{Common, LiveStoreRing, PartitionRing} generatorDeps : []string{Common, MemberlistKV, PartitionRing, GeneratorRingWatcher} // ... SingleBinary: {BackendScheduler, BackendWorker, QueryFrontend, Querier, Distributor, MetricsGenerator, LiveStore},distributor通过 partition ring 将 trace 写入 Kafkalive-store、metrics-generator、block-builder分别作为 Kafka 消费者从分区中消费数据PushSpansToKafka true、ConsumeFromKafka truequerier需要配置 frontend worker 地址且当target Querier时启用 store 轮询modules.goquery-frontend负责分片搜索任务同样需要感知 block 列表target QueryFrontend时启用轮询modules.gobackend-scheduler作为单例调度器backend-worker通过 gRPC 向 scheduler 领取任务执行压缩与清理微服务模式适用场景生产环境部署高 trace 数据量需要独立扩缩容需要高可用与隔离的故障域failure domains希望独立扩展写入吞吐、查询性能与近期数据recent-data容量微服务模式的隔离优势微服务模式为每个组件提供独立扩缩容和隔离的故障域querier 崩溃不会影响数据写入ingestionblock-builder 重启不影响查询可用性live-store 可以跨可用区availability zones部署以获得高可用这一点在readyHandler中也有所体现live-store 在就绪前会确保已追平 Kafka 消费位点has caught up with Kafka before serving queries见 app.go从机制上保障了微服务模式下查询数据的可用性。微服务模式配置示例仓库中的 example/docker-compose/distributed 演示了分布式部署其 tempo.yaml 展示了微服务模式的关键配置要点server: http_listen_port: 3200 distributor: receivers: otlp: protocols: grpc: endpoint: distributor:4317 http: endpoint: distributor:4318 memberlist: abort_if_cluster_join_fails: false bind_port: 7946 join_members: - live-store-zone-a-0:7946 - live-store-zone-a-1:7946 - live-store-zone-b-0:7946 - live-store-zone-b-1:7946 backend_worker: backend_scheduler_addr: backend-scheduler:3200 compaction: block_retention: 1h ring: kvstore: store: memberlist querier: frontend_worker: frontend_address: query-frontend:9095 storage: trace: backend: s3 s3: bucket: tempo endpoint: minio:9000 access_key: tempo secret_key: supersecret insecure: true从中可以看到微服务模式的几个典型特征memberlist用于组件之间的 ring 发现与 KV 共享join_members指向 live-store 各副本backend-worker显式指定backend_scheduler_addr连接调度器querier的frontend_worker.frontend_address指向 query-frontend 的 gRPC 端口存储后端切换为对象存储此处为兼容 S3 的 MinIO符合生产部署要求分布式示例还包含了 Kafka 兼容队列Redpanda见 redpanda-console.yaml与 memcached 缓存层tempo.yaml关于 Kafka 的更详细配置broker 地址、SASL/TLS、消费组等可参考 configure-kafka.md。选择模式决策对照表考虑因素单体模式Monolithic微服务模式Microservices是否需要 Kafka否是扩缩容方式单进程垂直扩容每个组件独立扩缩容故障隔离所有组件共享资源每个组件拥有隔离的故障域运维复杂度低较高需要管理更多进程适用场景入门、开发环境数据量 ≤ 25-35 MB/s生产、高数据量、高可用选择时的核心判断依据数据规模低于 25-35 MB/s约 55k-80k spans/s且处于评估/开发阶段单体模式足够一旦接近或超过该阈值或对写入、查询、近期数据容量有独立扩展诉求应迁移到微服务模式。可用性要求单体模式因 backend-scheduler 单例限制不支持多实例高可用生产环境的高可用必须采用微服务模式。运维资源单体模式只有一个进程、一份配置运维极简微服务模式需要同时运维多个进程、Kafka 队列与对象存储但换来的是弹性与隔离性。下一步若要深入了解整体架构、各组件职责、扩展指南与迁移指导可阅读架构相关的 Deployment modes 参考文档 及模块源码 modules.go理解每个 target 的初始化逻辑与依赖关系。集群规模规划请参考 Size the cluster规划集群规模其中给出了 distributor、live-store、block-builder、querier、query-frontend、backend-scheduler、backend-worker 等组件在微服务模式下的参考副本数与资源规格例如 distributor 每 10MB/s 流量 1 副本、live-store 每 6-10MB/s 流量 1 副本且通常跨可用区部署、query-frontend 建议 2 副本以保证高可用。实际部署请参考 Deploy your Tempo instance部署 Tempo 实例以及仓库中的可运行示例 example/docker-compose/single-binary 与 example/docker-compose/distributed。【免费下载链接】tempoGrafana Tempo is a high volume, minimal dependency distributed tracing backend.项目地址: https://gitcode.com/GitHub_Trending/tempo1/tempo创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考