资讯详情

Grafana Tempo 分区环(Partition Ring)架构解析:分区状态机、所有权模型与弹性扩缩容实战指南

发布时间:2026/9/18 23:46:06

500+
企业客户服务经验
120+
行业领域内容覆盖
3000+
原创页面设计沉淀
98%
客户满意度

Grafana Tempo 分区环(Partition Ring)架构解析:分区状态机、所有权模型与弹性扩缩容实战指南

Grafana Tempo 分区环Partition Ring架构解析分区状态机、所有权模型与弹性扩缩容实战指南【免费下载链接】tempoGrafana Tempo is a high volume, minimal dependency distributed tracing backend.项目地址: https://gitcode.com/GitHub_Trending/tempo1/tempo导读分区环partition ring是 Grafana Tempo 中用于追踪哪些分区存在、处于何种状态、由哪些组件拥有的分布式元数据机制。它借助 memberlist 的 gossip 协议在集群内传播是 distributor分发器、live-store实时存储与 block-builder块构建器之间协调写入路径的核心纽带。读完本文你将掌握 Tempo 自有分区与 Kafka 分区的区别、pending/active/inactive 三态状态机的完整生命周期以及如何在多可用区部署中安全地扩缩容 live-store。一、什么是分区环在 Tempo 的 ingest写入路径中数据从 distributor 流入 Kafka再由 live-store 消费、由 block-builder 落盘。要协调这条链路上的谁能写、谁能读、谁拥有哪块数据Tempo 需要一份集群级的共享视图——这就是分区环。根据官方架构文档 partition-ring.md 的定义The partition ring is the mechanism Tempo uses to track which partitions exist, their current state, and which components own them.在实现层面分区环的数据结构由pkg/ring/ring.go中的PartitionRing与PartitionRingDesc承载并在 modules/livestore/partition_ring.go 中通过PartitionRingConfig配置。live-store 启动时会创建ring.NewPartitionInstanceLifecycler见 modules/livestore/live_store.go该 lifecycler 负责在 KVStore默认 memberlist中维护分区状态并参与环的写入而环本身以livestore-partitions为名称见 live_store.go 的PartitionRingKey/PartitionRingName常量。默认情况下环的后端 KVStore 被硬编码为memberlistcfg.KVStore.Store memberlist // Override default value.——这段逻辑位于 modules/livestore/partition_ring.go。这意味着你无需额外部署 Consul/etcd只要所有相关组件distributor、live-store、block-builder加入同一个 memberlist 集群就能共享分区环视图。二、Tempo 分区与 Kafka 分区的区别这是理解分区环的第一步也是最容易混淆的一点Tempo 维护的是自己概念里的 partition它与 Kafka 分区在逻辑上是两套东西只是通常情况下保持 1:1 的映射关系。两者的本质差异可以归纳为下表维度Kafka 分区Tempo 分区分区环中的 partition归属Kafka 集群由 broker 管理Tempo 分区环由 live-store 的 lifecycler 管理状态无显式状态在线/下线由 broker 决定显式三态pending / active / inactive所有权由 consumer group 协调每个可用区AZ一个 live-store 拥有者生命周期操作需要修改 Kafka 配置或调 admin API直接在环上创建、激活、停用无需动 Kafka传播方式Kafka 元数据memberlist gossip为什么要多此一举因为 Kafka 分区本身不提供暂时不接受写入或此分区处于只读回放期这类业务语义。分区环给了 Tempo 独立控制分区状态pending/active/inactive、所有权哪个 live-store 拥有哪个分区和生命周期管理无需修改 Kafka 配置即可创建、激活、停用分区的能力——这正是文档中强调的 the partition ring gives Tempo independent control。从源码看这种独立性体现在live-store 通过ingest.IngesterPartitionID计算自己负责的分区 ID见 live_store.go而消费者侧block-builder通过pkg/ingest/balancer.go的NewCooperativeActiveStickyBalancer读取分区环来决定哪些分区应该被处理见 pkg/ingest/balancer.go。三、分区三态状态机每个环中的分区都有且仅有以下三种状态之一。这是整个分区环设计的核心。Pending待定Pending 是新分区创建后的初始状态此状态下没有任何读写流量。典型场景一个新的 live-store 实例启动在环中查找自己的分区发现不存在于是以 pending 状态创建它。分区停留在 pending直到同时满足两个条件有足够多的 owner 注册由min_partition_owners_count控制默认 1最短等待期已过由min_partition_owners_duration控制默认 10 秒。之后拥有该分区的 live-store 会自动将其提升为 active。Active活跃Active 是正常运转状态distributor 只向 active 分区写入数据querier 从这些分区读取。pending → active 的转换条件与上述两个配置直接对应。其设计意图在文档中写得很清楚确保所有可用区都有时间注册它们的 live-store 实例之后流量才开始流入。在多可用区场景下min_partition_owners_count通常应该设置为可用区数量从而保证每个分区在被激活前已经具备跨区副本。Inactive停用Inactive 是只读状态distributor 停止向该分区写入但 querier 仍可读取。分区在缩容scale down时被标记为 inactive。它必须停留足够长的时间以便block-builder 把该分区的全部剩余数据 flush 到对象存储querier 不再依赖 live-store 提供该分区的近期数据。这段宽限期由delete_inactive_partition_after配置控制默认 13 小时。宽限期过后分区就可以被安全地删除连同它的 owner live-store 一起移除。三个关键配置项以上三种状态转换分别由PartitionRingConfig中的三个参数驱动它们在 modules/livestore/partition_ring.go 中注册默认值如下配置项命令行 flag默认值作用min_partition_owners_count-live-store.partition-ring.min-partition-owners-count1一个 PENDING 分区在被切换为 ACTIVE 前需要等待的最小 owner 数量min_partition_owners_duration-live-store.partition-ring.min-partition-owners-duration10s最小 owner 数量被满足后还需等待多久才切换为 ACTIVEdelete_inactive_partition_after-live-store.partition-ring.delete-inactive-partition-after13hINACTIVE 分区满足该时长且无 owner 注册后即可被删除设为 0 则禁用分区删除注意三个参数的注释都明确标注了它们与 dskit 中ring.PartitionInstanceLifecyclerConfig的映射关系分别对应WaitOwnersCountOnPending、WaitOwnersDurationOnPending和DeleteInactivePartitionAfterDuration见 partition_ring.go。ToLifecyclerConfig方法partition_ring.go就是把这些配置翻译成 lifecycler 配置的地方。完整配置示例live_store: partition_ring: kvstore: store: memberlist prefix: collectors/ min_partition_owners_count: 2 # 例如双可用区部署建议设为 2 min_partition_owners_duration: 10s delete_inactive_partition_after: 13h这段 YAML 在仓库中有多处真实佐证e2e 测试基座 integration/util/config-base.yaml 中配置了partition_ring.kvstore.store: memberlist官方配置清单 docs/sources/tempo/configuration/manifest.md 展示了带默认值的完整结构微服务部署模板 operations/jsonnet-compiled/microservices/gen/ConfigMap-tempo-live-store.yaml 中按实际场景把delete_inactive_partition_after调成了35m。四、所有权模型谁拥有分区分区环不仅记录状态还记录所有权。Tempo 的三个核心组件以不同方式参与其中。Live-stores实时存储每个 Tempo 分区被每个可用区中的一个 live-store 拥有。例如在双可用区zone-aware部署中每个分区有两个 owner——每个可用区各一个两者独立消费同一个 Kafka 分区互为副本。live-store 启动时的行为逻辑见 live_store.go 附近的回放逻辑以及 partition_ring.go 的 lifecycler 装配计算自己的ingestPartitionID检查分区环中是否存在该分区若已存在 → 以 owner 身份加入join若不存在 → 以 pending 状态创建分区等待足够多的 owner 注册。此外RemoveOwnerOnShutdown配置默认trueflag 为-live-store.remove-owner-on-shutdown控制正常关闭时是否从环中移除 owner 注册避免留下过期条目SetRemoveOwnerOnShutdown在 live_store.go 中被调用关闭时还会检查分区状态——若分区为 Inactive即此前已被排水则跳过 lookback 回放见 live_store.go。Distributors分发器distributor 读取分区环来确定哪些分区是 active 的只向 active 分区发送数据。环告诉 distributor 应该写哪些 Kafka 分区。在源码中distributor 持有ring.PartitionRingReader见 modules/distributor/distributor.go并通过 ShuffleShard 等机制确定目标distributor.go。这意味着谁能收到新数据完全由分区环的 active 状态决定——这正是扩缩容时流量自动迁移的基础。Block-builders块构建器每个 block-builder 实例根据其序号ordinal ID和partitions_per_instance设置计算自己拥有哪些 Kafka 分区。分区环对 block-builder 的影响是间接的环决定了哪些分区会从 distributor 收到数据而 block-builder 只消费存在且非 pending的分区。分区归属的计算逻辑在 modules/blockbuilder/config.goassignedPartitions : make([]int32, 0, c.PartitionsPerInstance) for i : 0; i c.PartitionsPerInstance; i { assignedPartitions append(assignedPartitions, id*int32(c.PartitionsPerInstance)int32(i)) }即实例id拥有分区id*N到id*NN-1N为partitions_per_instance。而实际消费时blockbuilder.go 的getAssignedPartitions会与分区环核对只有环中存在、且状态为 Active 或 Inactive 的分区才会被消费Pending 分区被排除并同步上报tempo_block_builder_owned_partitions指标label 含 partition 与 state。五、扩容Scaling up实战扩容流程非常简单核心思路是加一个 live-store 实例其余自动完成可选但推荐先扩容 Kafka 分区确保对应的 Kafka 分区已存在。文档明确要求 A corresponding Kafka partition must exist. Add Kafka partitions first if needed.部署一个新的 live-store 实例它会在环中创建一个新分区pending 状态。等待 owner 注册与等待期当足够多的 owner 注册且min_partition_owners_duration过去后分区自动转为 active。流量自动迁移distributor 从环上看到新 active 分区开始向新分区写入。整个过程不需要手动操作环、不需要重启 distributor、不需要改动 Kafka 配置——新增实例自举了分区的创建与激活。六、缩容Scaling down实战缩容比扩容多一个关键的前置步骤必须先把分区标记为 inactive而且是在 live-store 还在运行的时候。标记目标分区为 inactivelive-store 保持运行。此时 distributor 立即停止向该分区写入等待 block-builder 把该分区的剩余数据 flush 到对象存储等待 querier 停止依赖该分区的 live-store 近期数据移除 live-store 实例分区最终从环中被清理经过delete_inactive_partition_after宽限期且要求该分区已无 owner 注册。缩容注意事项文档给出了一个非常明确的警告跳过 inactive 步骤、直接拔掉 live-store会导致该分区的近期数据暂时不可用除非存在可用区副本。原因是还有未 flush 的数据停留在该 live-store 的 WAL / 内存中分区环里没有 inactive 标记block-builder 不会为此触发排空唯一兜底手段是另一个可用区的副本仍在运行。因此规范的缩容永远走inactive → 排水 → 删除三步而不是直接删实例。从源码印证block-builder 会持续消费 Inactive 分区见上文getAssignedPartitions对IsInactive的包含这正是排水期数据能被落盘的原因而 live-store 检测到分区为 Inactive 时会跳过 lookback 回放live_store.go避免重启后重复消费已排水数据。七、memberlist 传播与一致性权衡分区环的状态通过 memberlist 的 gossip 协议传播文档明确说明正常情况下环的变更新分区、状态迁移在几秒内传播到整个集群网络分区或高集群变更churn期间传播可能延迟导致不同组件对环有一时的不一致视图。Tempo 对这种短暂不一致做了优雅处理文档归纳了两种场景场景表现兜底机制distributor 写入了一个 live-store 尚未看到的刚激活的分区该 live-store 暂未消费这些数据live-store 追上环视图后数据会被消费最终一致querier 联系了一个尚未拥有该分区的 live-store得到空响应数据最终可从另一个 live-store 或对象存储读取也就是说环的不一致只会带来短暂的最终一致延迟不会造成数据丢失或查询错误。这也解释了为什么 Tempo 把分区激活设计成等 owner 齐 等时长的保守策略——本质上是在用状态机的延迟换取一致性窗口的收敛。需要强调的是memberlist 传播能力同时被多个环使用除了分区环还有 live-store 自身的成员环tempo_live_store见 live_store.go 中两套 lifecycler 的创建。memberlist 配置项如bind_port、join_members、abort_if_cluster_join_fails在 e2e 基座 integration/util/config-base.yaml 中有完整的可运行示例可参考。八、关键源码路径速查如果你想深入阅读分区环的实现以下文件是最直接的入口主题路径关键位置分区环配置与默认值modules/livestore/partition_ring.goPartitionRingConfig、RegisterFlags、ToLifecyclerConfig分区环装配与 lifecyclermodules/livestore/live_store.goKVStore 创建、NewPartitionInstanceLifecycler、NewBasicLifecycler关闭与 owner 清理modules/livestore/live_store.goRemoveOwnerOnShutdown、停止 lifecyclerdistributor 读取环modules/distributor/distributor.goPartitionRingReader字段block-builder 分区归属modules/blockbuilder/config.goPartitionsPerInstance、AssignedPartitionsblock-builder 过滤 pendingmodules/blockbuilder/blockbuilder.gogetAssignedPartitions只消费 Active/Inactive消费者侧环形 balancerpkg/ingest/balancer.goNewCooperativeActiveStickyBalancer完整配置清单含默认值docs/sources/tempo/configuration/manifest.mdlive_store.partition_ring全字段e2e 测试基座integration/util/config-base.yamllive_store.partition_ring最小配置结语分区环是 Tempo 写入路径的指挥中心它用一套独立于 Kafka 的分区状态机把谁能写、谁能读、谁拥有的决策权掌握在 Tempo 自己手里。pending/active/inactive 三态配合min_partition_owners_count、min_partition_owners_duration、delete_inactive_partition_after三个旋钮让多可用区部署下的安全扩缩容成为可配置、可预期、可观测的常规操作。理解这层机制是运维 Tempo 微服务模式集群、诊断写入延迟与数据可用性问题的基础。【免费下载链接】tempoGrafana Tempo is a high volume, minimal dependency distributed tracing backend.项目地址: https://gitcode.com/GitHub_Trending/tempo1/tempo创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
热门专题

继续阅读更多专题内容

围绕企业服务、数字化转型与官网运营的常青话题,持续输出深度内容

企业官网建设指南 企业托管服务模式 财税政策与解读 企业数字化转型 官网SEO与获客 网站安全与运维
配套服务

读完这篇文章,了解更多服务

从整站搭建到SEO布局,17项核心服务助您打造高转化的企业官网

01

企业托管整站搭建

从信息架构到栏目预留,搭建可生长的企业站点骨架,每个页面独立原创设计。...

了解详情
02

规整可信网页设计

雪地靴温暖风原创设计,金属铜线条贯穿全页,拒绝通用模板与AI流水线。...

了解详情
03

企业服务SEO布局

关键词体系与语义化结构,从建站源头为搜索排名而生。...

了解详情
04

业务预约咨询表单

多场景表单与线索收集体系,把访问流量转化为可追踪的销售线索。...

了解详情
05

企业服务站点运维

安全巡检、数据备份与内容更新支持,全年守护网站稳定运行。...

了解详情
06

全终端商务适配

电脑、平板、手机一致呈现,移动端体验与转化同样出色。...

了解详情
需要专业建议?

让专业顾问为您解读行业趋势

关于企业官网建设、SEO获客与数字化转型的任何疑问,欢迎一对一咨询我们的专业顾问。