返回资讯中心
外部精选
软件工程
#开发者实时流

Uber开源分片管理服务Shard Manager,最热主机CPU使用率降38%

来源标题:Shard Manager

Uber在cadence-workflow GitHub组织下开源了通用分片服务Shard Manager,将分片归属决策与应用逻辑分离。其首个接入服务在最热主机上CPU使用率降低38%。该服务提供负载感知的分片放置、客户端库和运维工具,Cadence是其在Uber的首个生产应用。

Hacker News 最新qainsights2026/11/12 · 今天28 分钟阅读

以下正文由 AI 翻译自 Hacker News 最新(原文版权归原站所有),可能存在偏差,重要内容请以原文为准。

Shard Manager 是 cadence-workflow GitHub 组织下提供的一个通用开源分片服务。它将分片归属决策与应用逻辑分离,提供负载感知的放置、客户端库和运维工具。尽管 Cadence 是它在 Uber 的第一个生产应用,但其集成模型支持任何分片服务。首个接入的服务显示,其最热主机的 CPU 使用率降低了 38%。

本文介绍该设计、它与 Cadence 的集成以及在 Uber 的生产结果。面对负载不均的工程师可以借鉴这些经验,评估显式分片放置是否有助于自己的系统。

Cadence 此前依赖 Ringpop 的 Go 实现(一个一致性哈希库)来分发分片。每个参与主机根据自身对集群成员关系的视图独立推导归属。

图 1:像 Ringpop 这样的哈希环方案可能导致分片分布倾斜,因为它们不考虑分片负载。

这种方法有三个局限。第一,按分片数量分发没有考虑分片负载的差异。第二,不一致的成员关系视图使归属难以诊断,因为没有权威的分配记录。第三,运维人员无法直接引导放置:要移动工作负载就得改变集群成员关系。

在 Cadence 的 history 和 matching 服务中,不均匀的分片放置造成了热点主机。没有自动扩缩器时,运维人员不得不不断增删主机来重新分配分片、缓解过载主机。有了自动扩缩器,系统会持续添加主机,直到所有主机都低于目标利用率,导致大量机器未被充分利用。对于一个每天处理数十亿请求的系统来说,这意味着要么持续投入运维精力,要么大量浪费容量。

这些局限促使我们构建一个将归属变为显式、可检查决策的服务。最终实现使用 Go、gRPC™ 和 etcd®,应用客户端负责上报负载并消费分配结果。

核心设计考量是共享服务应承担多少职责。应用保留处理其分片和定义有意义负载指标的责任;Shard Manager 负责放置和归属协调。这种分工让不同应用可以共用同一套基础设施,而无需采纳 Cadence 特有的处理逻辑。应用请求从不经过 Shard Manager,因为 Shard Manager 只编排谁拥有什么。

我们的设计灵感来自 Facebook® Shard Manager、Google® Slicer、Azure® Service Fabric 和 Apache Helix™。这些系统为将分片管理与应用处理分离提供了有用的先例。例如,Google Slicer 描述了一个控制平面,在请求路径之外做出放置决策,在平衡工作负载的同时限制迁移。

我们考虑过 Apache Helix,但其主要的 Java 接口难以与 Go 服务集成。Uber 开发了一个部分实现的 go-helix 客户端,已于 2020 年归档。Helix 客户端还直接与 Apache ZooKeeper™ 通信,并依赖其 Helix 特有的数据布局。采用这种架构会带来运维开销,包括需要部署 ZooKeeper 集群。我们选择了将存储细节与应用客户端分离的服务接口,并计划让 etcd 变为可选,从而移除一项基础设施依赖。

我们还考虑过将放置控制器嵌入分片服务本身。这样可以避免运维一个独立服务,但会把管理状态分散到各应用,并给主机服务增加协调职责。独立服务能更清晰地分离职责,并为其他应用提供共享基础。

若干需求指导了架构设计:

这些考量最终促成了一个带有 Go 客户端和 gRPC 接口的独立服务。应用上报分片负载并处理分配的工作,而 Shard Manager 协调归属与放置。

该架构有五个主要组件:

命名空间为不同的分片集合分离配置和均衡决策。

图 2:Shard Manager 将分片分配给 Cadence Matching 服务(执行者)主机。

图 3:Cadence Frontend 服务(观察者)接收分片映射。

图 4:Cadence Frontend 服务(观察者)将分片请求路由到正确的 Matching 服务(执行者)主机。

在 Cadence 中,Matching 主机处理 task-list 分片,而 Frontend 使用观察者客户端定位其归属者。一个服务也可以同时承担两种角色,既需要处理本地分片,又需要将请求路由到对等节点。

与之前哈希环方案的关键架构区别在于:显式归属结合应用上报的负载。放置可以随工作负载状况变化而调整,而无需改变成员关系。

Shard Manager 的运维接口是 smctl 命令行工具。运维人员可以检查分片的归属者、列出执行者、排空主机,以及排空或恢复单个分片。

图 5:Shard Manager CLI 命令示例,展示分片检查和执行者排空。

对于应用开发者,集成通过 Go 客户端完成。应用提供一个带生命周期方法和负载报告的分片处理器。执行者客户端管理心跳和分配更新,而观察者客户端提供归属查询。

一个关键的工程权衡是在响应性与不必要的分片迁移之间取得平衡。对每个短暂的峰值都做出反应会导致反复重新分配,而反应太慢又会延长过载。

贪心均衡算法通过平滑后的负载测量、上下阈值、迁移预算以及归属变更后的冷却期来解决这个问题。它考虑能改善均衡的迁移,并选择一个能让源和目标负载更接近的分片。

(原文较长,此处译出前 6000 字,完整内容请点「打开原文」。)

正文由 探How 从来源站点 RSS 同步,内容未经改写;遇到排版缺失或需要图片、视频时请以原文为准。

打开原文
去社区讨论 →