知识卡片

权重Hash分片:均匀分散热点用户,避免数据倾斜

普通读书笔记卡

内容

简单的UID Hash分片有一个隐藏的缺陷:它只保证不同UID被打散到不同分片,却不保证”高活跃度用户”这个更关键的维度被均匀分散——如果碰巧某几个粉丝量巨大、发帖频繁的头部用户被哈希到了同一个分片,这个分片承受的实际数据量和访问压力会远高于其他分片,造成负载倾斜,即使从UID数量上看各分片是”均匀”的。微博Feed存储案例的解法是引入”权重”这个额外维度:权重根据每个用户的微博数量、粉丝数等能反映活跃度和访问热度的指标离线计算得出,分片算法在计算Hash时同时结合UID和权重,明确要求满足两个约束——同一个UID的数据必须落在同一个库(保证数据不会因为分片被拆散到多处、破坏查询的一致性),而权重接近的用户应当尽量均匀地分散到不同库(真正解决热点用户扎堆的问题)。由于权重会随用户活跃度变化而周期性调整,被重新计算权重的用户理论上需要做一次数据迁移(把数据从旧分片挪到权重调整后对应的新分片),但因为触发权重调整的用户占总体比例很小,这种迁移的实际数据变动量是可控的;而历史数据完全不需要权重概念,也就完全不需要考虑这类迁移。这个设计给出了一条应对”分片依据的单一维度掩盖不了真实负载分布”问题的通用思路:当发现某种简单的分片键(如UID)本身的分布并不能代表真实的负载分布时,应该主动引入一个能反映真实负载特征的额外维度(这里是权重)参与分片计算,而不是继续在原有单一维度上打转。

参考来源

- 位置:《高可用架构(第1卷)》第2章《高可用架构原理与分布式实践》"2.9 微博分布式存储考试题:案例讲解及作业精选"节,"2.9.4 案例精选"(源文件:_epub-src/OEBPS/Text/Chapter2_9_5.xhtml) - 结论依据:原文说明"根据UID+权重的Hash算法分库。权重可以根据每个UID的微博ID数量、粉丝数等指标离线计算……其中Hash算法需保证:同一UID需落在一个库;权重接近的用户尽量均匀落在不同库",并说明"权重周期性调整,对于调整权重的用户,需要重点考虑当前n日数据的数据迁移方案。但由于调整权重的用户占比较少,所以迁移时的数据变动应该较小",共同支撑本卡片结论。 - 原始内容:根据UID+权重的Hash算法分库。权重可以根据每个UID的微博ID数量、粉丝数等指标离线计算……其中Hash算法需保证:同一UID需落在一个库;权重接近的用户尽量均匀落在不同库。