Uber引入子集群改造M3DB分片策略
Uber对其分布式时序数据库M3DB的分片放置机制进行了调整,核心做法是把集群划分为固定规模的子集群,让节点故障、日常维护和扩容带来的影响被限制在更小范围内。旧机制下,随着分片之间的依赖关系增多,单个节点故障可能波及接近整个集群,影响范围最高可达(n-1)/n。
M3DB会将数据切分为多个分片,并在不同节点之间复制。分片放置算法负责决定每个分片归属,同时保证副本隔离,例如避免同一分片的多个副本落在同一机架或同一可用区。原有方案在中小规模集群中运行效果较好,但当节点数量持续增加后,拓扑依赖变复杂,恢复和维护成本也随之上升。
在旧模型中,只要满足副本不在同一隔离组内,任意节点都可能持有某个分片,这会形成全局依赖图。一次拓扑变化可能影响O(N)个节点。即便集群按三个可用区隔离、复制因子为3,单个节点仍可能与多达66.67%的其他节点共享数据,导致恢复任务增加,也让许多运维操作不得不串行执行。
新方案将节点分成固定大小的子集群,并让不同子集群拥有互不重叠的分片空间。以一个12节点、复制因子为3的集群为例,如果每个子集群包含6个节点,则集群会被分成两个子集群,各自负责一半分片;在每个子集群内部,M3DB仍会把副本分散到不同隔离组中。
扩容时,系统需要把部分分片从已有子集群迁移到新的子集群。Uber采用贪心算法评估每个候选分片从源子集群移除后的影响,并选择能让剩余节点负载尽量均衡的分片。这样可以避免额外再平衡,也减少同一分片被移动两次带来的网络传输和引导开销。该算法排序复杂度为O(SlogS),模拟评估开销为O(S×N),其中S为候选分片数量,N为子集群内节点数。
M3DB原有放置流程中,目标节点接管分片前需要从现有对等节点流式传输数据,因此不必要的分片迁移本身就是运维负担。子集群方案也带来限制:所有实例权重必须相同,扩容要按子集群规模成批进行,子集群大小必须是复制因子的整数倍,并且不支持通过AddReplica接口修改复制因子。扩容期间可能短暂出现跨子集群共享分片,同时系统同一时刻只允许存在一个未完整的子集群。
Uber没有为该方案引入原子化的子集群级操作,而是保留M3DB现有的实例级放置操作,以维持与既有工具链兼容,并避免一次触发大量分片迁移造成大规模引导。当前M3DB放置策略中已加入子集群放置以及每个子集群实例数量等相关字段。
本文基于公开渠道信息整理,内容可能存在不准确或遗漏之处,不代表本站立场,如内容涉及侵权或错误,请联系我们处理。
阅读原文