4. Redis 集群架构与数据分片:Redis Cluster 原理、哈希槽(Hash Slot)分配、数据分片对热点分散的作用

4.1 为什么需要 Redis Cluster?

在单机 Redis 或主从架构中,数据全部存储在一台(或一组主从)节点上,存在两个核心瓶颈:

  • 容量瓶颈:单机内存上限(通常 64GB~256GB)限制了总数据量。
  • 吞吐瓶颈:单节点处理能力受限于 CPU 单核性能,QPS 上限约 10~20 万。

Redis Cluster 通过无中心化分片架构,将数据自动分散到多个节点,实现线性扩展。每个节点只负责一部分数据,整体容量和吞吐量随节点数增加而提升。

适用场景:数据量超过单机内存 70%、写入 QPS 超过 5 万、需要 99.99% 可用性的生产环境。

4.2 哈希槽(Hash Slot)分配原理

Redis Cluster 采用固定 16384 个哈希槽的分片方案。每个键通过 CRC16 算法计算哈希值,再对 16384 取模,确定所属槽位。槽位到节点的映射关系由集群元数据维护。

// 槽位计算伪代码
slot = CRC16(key) % 16384

// 示例:键 "user:1001" 的槽位
slot = CRC16("user:1001") % 16384  // 假设结果为 12345

槽位分配支持两种模式:

分配模式 操作方式 适用场景
手动分配 CLUSTER ADDSLOTS 命令逐个指定 小规模集群、精确控制数据分布
自动分配 redis-cli --cluster create 自动均衡 生产环境推荐,减少人为错误
关键约束:槽位必须全部分配(0~16383),不能有空缺。未分配的槽位会导致对应键无法写入。

4.3 数据分片对热点分散的作用

热点键(如爆款商品、大 V 用户)集中访问同一节点是性能瓶颈的常见原因。哈希槽分片通过以下机制分散热点:

  • 键级分散:不同键的 CRC16 哈希值不同,大概率落入不同槽位,从而分布到不同节点。
  • 槽位迁移:当某个节点负载过高时,可将该节点部分槽位迁移到其他节点,实现负载再平衡。
  • 标签哈希(Hash Tag):强制将多个相关键映射到同一槽位,用于事务或管道操作。
热点分散效果指标:在 6 节点集群中,单个热点键的访问压力最多被分散到 1 个节点;但通过槽位迁移,可将该节点上的其他冷数据移走,使热点节点专注处理热点键,整体吞吐提升 3~5 倍。

4.4 Redis Cluster 架构总览

下图展示了一个 6 节点(3 主 3 从)Redis Cluster 的典型架构,以及哈希槽的分布逻辑:

Redis Cluster 架构与哈希槽分布(3 主 3 从) 主节点 A 槽位 0~5460 5461 个槽 主节点 B 槽位 5461~10922 5462 个槽 主节点 C 槽位 10923~16383 5461 个槽 从节点 A1 副本 从节点 B1 副本 从节点 C1 副本 客户端(Smart Client) 说明:每个主节点负责一段连续哈希槽;从节点仅复制数据,不处理写请求;客户端通过 MOVED 重定向或集群映射直接访问正确节点

4.5 槽位迁移与热点再平衡

当集群出现热点节点时,可通过在线槽位迁移将部分槽位从高负载节点移至低负载节点。迁移流程如下:

  1. 标记迁移:在源节点执行 CLUSTER SETSLOT slot MIGRATING target_node_id。
  2. 标记导入:在目标节点执行 CLUSTER SETSLOT slot IMPORTING source_node_id。
  3. 数据迁移:使用 MIGRATE 命令将槽位内所有键从源节点移至目标节点。
  4. 槽位归属:在集群所有节点广播 CLUSTER SETSLOT slot NODE target_node_id。
生产建议:使用 redis-cli --cluster rebalance 自动检测负载不均并触发迁移。迁移期间,客户端可能收到 ASK 重定向,需在客户端实现 ASKING 命令支持。

4.6 哈希标签(Hash Tag)的使用与陷阱

哈希标签允许将多个键强制映射到同一槽位,语法为在键名中使用 {...} 包裹标签部分:

// 以下两个键会落入同一槽位
SET user:{1001}:profile "data1"
SET user:{1001}:orders "data2"

// 槽位计算只取标签部分
slot = CRC16("1001") % 16384
使用场景 示例 注意事项
事务操作 MULTI/EXEC 操作同一用户的多条数据 标签内字符串不宜过长,避免哈希冲突
管道批量写入 批量写入同一业务实体的关联数据 避免所有键使用相同标签,否则全部集中到一个节点
热点键分组 将热点商品及其库存、详情键分组 分组后该节点负载会升高,需配合槽位迁移
常见陷阱:滥用哈希标签会导致数据倾斜。例如将所有键使用 {cache} 标签,则全部数据落入同一节点,完全丧失分片优势。生产环境中,标签应仅用于必须跨键操作的场景,且标签值应具有足够基数。

4.7 数据分片对热点分散的量化效果

以下对比展示不同分片策略下的热点分散能力:

分片策略 热点键分布 单节点最大 QPS 集群总 QPS(6 节点)
无分片(单机) 全部集中 15 万 15 万
固定取模分片 均匀分布 15 万 ~90 万
哈希槽分片(无标签) 均匀分布 15 万 ~90 万
哈希槽分片(含标签) 按标签分组 15 万(标签内热点) 受标签分布影响

从数据可见,哈希槽分片在无标签滥用时,能将热点均匀分散到所有节点,实现接近线性的吞吐扩展。实际生产环境中,配合槽位迁移和客户端缓存路由表,可将热点节点的负载波动控制在 ±10% 以内。

最佳实践:在集群初始化时,使用 redis-cli --cluster create --cluster-replicas 1 自动分配槽位;运行期间每 30 分钟执行一次 --cluster rebalance 检查负载均衡;监控节点 CPU 和内存,当单节点 CPU 超过 80% 时触发槽位迁移。