← 返回题目列表

分布式缓存如何分片?一致性哈希有什么作用?

高频 中等 第 2 / 26 题 更新于 2026/09/30
缓存分片一致性哈希哈希槽扩容
学习 AI 实战项目

简化版

缓存分片是按 Key 将数据和请求路由到多个节点,常见方式有客户端一致性哈希、代理分片和服务端固定哈希槽。普通 %N 在节点数变化时会重映射大量 Key;一致性哈希或固定槽把变更限制到部分区间,降低迁移和缓存失效,但仍需虚拟节点/槽均衡、拓扑版本和故障处理。

详细版

客户端分片路径短、性能高,但所有客户端必须及时获得一致拓扑;代理分片治理集中,却增加一跳和代理容量;Redis Cluster 等服务端分片用固定 slot 管理迁移,客户端根据重定向更新路由。选型要看运维、跨语言客户端、扩容频率和多 Key 操作。

一致性哈希把节点和 Key 映射到环,节点增删只影响相邻区间;虚拟节点改善真实节点少时的倾斜并表达权重。固定哈希槽则先将 Key 映射到稳定槽,再迁移槽的所有权,更容易审计和控制。两者都不能拆散单个 Hot/Big Key,也不能保证业务 Key 自然均匀。

扩缩容需记录新旧拓扑版本,分批迁移并处理迁移期间的读写路由、重试和校验。跨分片 MGET、事务和 Lua 受限,应通过 hash tag/聚合根控制同槽,但滥用会产生热点。监控槽/虚拟节点的 Key 数、内存、QPS和最大/平均比。

完整版教学

一、分片解决的是单节点上限

单节点内存、CPU 和网卡都有上限。分片将 Key 空间划分给多个主节点,让总容量随节点数扩展;副本解决可用性,不等于分片容量。一次请求先根据 Key 计算路由,再访问负责该区间的节点。

理想分片要求数据量、QPS 和带宽都均衡。仅 Key 数平均不够:一个 2GB Big Key 或 8 万 QPS Hot Key 仍会压垮单节点。分片算法以 Key 为最小单位,不能自动拆单 Key。

记忆钩子:分片扩展“不同 Key 的总容量”,副本提高“同一分片的可用性”,两者职责不同。

二、三种分片位置的取舍

方式路由位置优点代价
客户端分片应用 SDK少一跳、性能高多语言拓扑一致和升级复杂
代理分片中间代理治理集中、客户端简单代理延迟、容量与高可用
服务端分片集群协议拓扑/迁移由集群管理客户端需支持重定向,操作受限

客户端一致性哈希适合简单缓存池;企业多语言环境常用代理统一配额与迁移;Redis Cluster 使用 16384 个固定槽,由客户端缓存映射并处理 MOVED/ASK。不存在无成本方案。

三、普通取模为何不利于扩容

规则 node = hash(key) % N 把节点数写进映射。N 从 10 变 11 时,大部分 Key 的余数变化,导致大面积缓存 miss 和数据迁移。理论上只有约 1/11 Key 仍可能留在原映射,具体取决于 hash 分布。

hash(key)=37
N=10 -> node7
N=11 -> node4

取模并非永远错误:节点集合固定、数据可全量重建的小系统可以使用;但频繁扩缩容时需要间接层减少重映射。

四、一致性哈希和虚拟节点

一致性哈希把 hash 空间首尾相连。Key 顺时针找到第一个节点;新增节点只接管其逆时针到自身的区间,删除节点则把原区间交给后继。理想均匀情况下新增第 N+1 个节点约迁移 1/(N+1) 数据,而不是大部分。

真实节点少时区间大小方差很大,所以每个物理节点映射成数百个虚拟节点散布在环上。高配置机器可分配更多虚拟节点表达权重。虚拟节点映射必须由所有路由方以同一版本使用,否则同一 Key 会被发往不同节点。

physical A -> A#1, A#2, ... A#160
physical B -> B#1, B#2, ... B#160
key -> hash ring point -> next vnode -> physical node

五、固定槽为什么更易运维

固定槽将 key -> slot 与 slot -> node 分开。扩容时 key 到 slot 的映射不变,只迁移部分槽的所有权;运维系统可记录进度、限速和回滚。Redis Cluster 使用 CRC16 与 16384 个 slot。

迁移期间源节点和目标节点会标记 importing/migrating。客户端访问迁移 Key 可能收到 ASK 临时重定向,迁移完成后收到 MOVED 并更新长期槽映射。客户端需限制重定向次数并刷新拓扑,不能把 ASK 当永久路由缓存。

槽数固定也有粒度:单个槽内若有 Big Key,迁移仍可能卡住;因此槽均衡和 Key 治理要一起做。

六、多 Key 操作和 hash tag

跨分片事务、Lua 和集合运算很难原子执行。Redis Cluster 通过 hash tag 让 {order:42}:detail 和 {order:42}:items 使用花括号内容计算同一槽,从而支持同槽多 Key 操作。

hash tag 应围绕小的聚合根。若所有订单都写 {order},会全部落在一个槽,彻底破坏分片。相反,热点复制 Key 若使用相同 tag,也会仍在同节点。

业务需要大量跨分片查询时,说明缓存 Key 模型或数据访问模式需要重新设计;可预聚合、并行读取但限制 fan-out,不能期待缓存集群提供廉价分布式事务。

七、扩容迁移与验证

扩容先评估节点容量和迁移带宽,生成槽/虚拟节点计划;小批迁移并监控源/目标 CPU、网络、延迟和复制 lag;校验 Key 数、抽样 checksum 和业务命中;逐步扩大。迁移流量必须给在线请求让路。

假设迁移 120GB,安全带宽 40MB/s,纯传输至少 120×1024/40 ≈ 3072s,约 51 分钟。实际还有扫描、重试和副本同步,应提前触发扩容。

topology_version: 184
slots_migrated: 2048
slots_total_plan: 4096
max_shard_to_avg_memory: 1.18
redirect_error_rate: 0.002%

八、常见误区与追问

  • 误区:一致性哈希扩容完全不迁移数据。 它只减少范围,新增节点仍需接管部分区间。
  • 误区:Key 数均匀就代表分片均衡。 value 大小和访问频率也必须均匀,Big/Hot Key 可单独打满节点。
  • 误区:副本越多总缓存容量越大。 副本复制同一数据用于可用性,不增加主分片可写数据空间。
  • 误区:hash tag 越多使用越方便。 过粗 tag 会把海量 Key 强制到同一槽,形成热点。
  • 追问:ASK 与 MOVED 有什么区别? ASK 是迁移期间一次性临时重定向,MOVED 表示槽所有权已长期变化,应更新路由缓存。
  • 追问:一致性哈希和固定槽怎么选? 前者适合客户端/代理灵活路由,后者便于集中管理、迁移与审计。
  • 追问:如何处理单个 Hot Key? 本地缓存、复制读副本、业务拆分或限流;增加普通分片不会自动分散它。

九、加强记忆

缓存分片按“Key 先映射、区间再归节点”理解。普通取模怕 N 改变;一致性哈希用环和虚拟节点缩小重映射;固定槽把 Key 映射与节点所有权解耦,更方便迁移。无论哪种方案,都要处理拓扑版本、迁移期间重定向、跨分片操作和 Hot/Big Key,不能把均衡完全交给哈希概率。