Redis Cluster 的哈希槽如何分配?扩容迁移有什么影响?

结论先行:Cluster 把键空间固定划分为 16384 个哈希槽,每个 key 通过 CRC16(key) % 16384 归属某个槽,槽再分配给不同主节点(每个主节点可带从节点做高可用)。扩缩容的本质是迁移槽:把部分槽及其中的 key 从源节点搬到目标节点,期间会有短暂的访问重定向与性能抖动。

一、哈希槽机制

  • 槽的划分:16384 个槽由集群各主节点分片持有,节点增减只影响槽的归属,key 与节点的映射关系通过槽间接完成;
  • key 定位:CRC16(key) % 16384 得到槽号,再查槽与节点的映射;使用哈希标签可以让指定 key 落在同一槽,例如 user:{1001}:cart 中的 {1001} 参与哈希计算,保证多 key 操作在同一节点执行;
  • 客户端路由:智能客户端缓存 slot 与节点的映射表,收到 MOVED 重定向时更新缓存重新请求;
  • 从节点角色:从节点不直接持有槽,只做副本备份,主节点故障时由对应从节点提升接管其槽位。

二、MOVED 与 ASK 的区别

重定向触发时机客户端处理
MOVED槽已彻底迁移到目标节点更新本地槽映射,下次直接访问新节点
ASK槽迁移过程中,key 正在搬移只对本次请求跟随到目标节点,不更新映射

三、扩容与迁移影响

  • 扩容流程:新节点加入集群(CLUSTER MEET)→ 执行 reshard 把源节点部分槽迁给新节点;
  • 迁移过程:源节点把槽置为 migrating、目标节点置为 importing,key 按批迁移;迁移期间命中的 key 若已搬走,源节点返回 ASK 让客户端去目标节点找;
  • 主要影响:客户端槽映射刷新产生零星重试;超大 key 迁移耗时且占带宽;迁移期间相关 key 的访问延迟上升,建议低峰执行并控制迁移并发;
  • 限制:多 key 命令、事务、Lua 脚本要求所有 key 在同一槽,否则报 CROSSSLOT 错误;
  • 数据倾斜:哈希对 key 分布并不完全均匀,热点 key 集中在某个槽会造成单节点热点,需配合热 key 打散治理;
  • 缩容同理:下线节点前先把其持有的槽迁移到其他节点,槽清空后才能安全下线,否则会丢数据;
  • 迁移节奏控制:生产上分批小流量迁移并观察延迟指标,避免一次性搬移过多槽造成抖动。

四、常用运维命令

redis-cli --cluster create 127.0.0.1:7000 127.0.0.1:7001 ... --cluster-replicas 1
redis-cli --cluster reshard 127.0.0.1:7000   # 交互式迁移槽
redis-cli --cluster info 127.0.0.1:7000      # 查看槽分配与节点状态

常见追问 / 记忆点

  • 追问:为什么是 16384 而不是更大?答:槽位信息要放进节点间心跳包,16384 在扩展性与消息开销之间取得平衡。
  • 追问:Cluster 能用 mget 跨槽吗?答:不能直接跨槽,需拆分请求或用哈希标签把相关 key 归入同槽。
  • 追问:迁移槽时旧节点还能提供服务吗?答:能,正在迁移的槽进入双写引导状态,通过 ASK 重定向保证读写不中断。
  • 记忆点:CRC16 算槽、槽归节点、MOVED 是确定搬迁、ASK 是迁移中临时引导。
笔记加载中…