Redis Cluster 是 Redis 官方提供的分布式集群方案,主要解决单机 Redis 在存储容量、性能和高可用性方面的限制。本文将深入解析 Redis Cluster 的 分片机制、哈希槽原理、高可用性设计、扩容缩容策略 以及 节点通信方式,帮助大家更好地理解 Redis Cluster 的核心原理和应用场景。
1. Redis Cluster 如何进行分片?
Redis Cluster 采用 哈希槽(Hash Slot) 机制进行数据分片,而不是简单的哈希取模。这种方式能够有效支持数据的动态迁移,避免一致性哈希扩容时的复杂性。
1.1 分片流程
-
计算 Key 的哈希值
- Redis 使用
CRC16(key)计算 16 位哈希值。
- Redis 使用
-
计算哈希槽编号
- 通过
CRC16(key) % 16384计算出 哈希槽编号(0~16383) 。
- 通过
-
映射到节点
- Redis Cluster 会将 16384 个哈希槽分配给多个主节点,不同节点负责不同范围的哈希槽。
例如,一个 3 节点的集群可以这样分配哈希槽:
- 节点 A 负责
0 ~ 5460 - 节点 B 负责
5461 ~ 10922 - 节点 C 负责
10923 ~ 16383
当客户端请求 user:123 时:
- 计算
CRC16("user:123") % 16384 = 5000, - 该 Key 属于 槽 5000,存储在 节点 A。
1.2 确定某个哈希槽(slot)由哪个节点负责
要知道 某个哈希槽(slot)由哪个节点负责,可以使用以下方法:
第一步:使用 CLUSTER SLOTS 命令
执行以下命令,可以获取整个 Redis Cluster 的哈希槽分配情况:
redis-cli -p 6379 cluster slots
输出示例:
1) 1) (integer) 0
2) (integer) 5460
3) 1) "192.168.1.10"
2) (integer) 6379
2) 1) (integer) 5461
2) (integer) 10922
3) 1) "192.168.1.11"
2) (integer) 6379
3) 1) (integer) 10923
2) (integer) 16383
3) 1) "192.168.1.12"
2) (integer) 6379
解释:
- 哈希槽 0 ~ 5460 由 192.168.1.10:6379 负责
- 哈希槽 5461 ~ 10922 由 192.168.1.11:6379 负责
- 哈希槽 10923 ~ 16383 由 192.168.1.12:6379 负责
第二步:使用 CLUSTER KEYSLOT 确定 Key 属于哪个槽
如果你想知道某个 Key 属于哪个哈希槽,可以执行:
redis-cli -p 6379 cluster keyslot mykey
示例输出:
(integer) 12545
这表示 mykey 属于 哈希槽 12545。
然后,再用 方法 1 确定该哈希槽属于哪个节点。
第三步:使用 CLUSTER NODES 查询节点信息
执行:
redis-cli -p 6379 cluster nodes
示例输出:
3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c 192.168.1.10:6379@16379 master - 0 1658901234567 1 connected 0-5460
4d4d4d4d4d4d4d4d4d4d4d4d4d4d4d4d 192.168.1.11:6379@16379 master - 0 1658901234567 2 connected 5461-10922
5e5e5e5e5e5e5e5e5e5e5e5e5e5e5e5e 192.168.1.12:6379@16379 master - 0 1658901234567 3 connected 10923-16383
可以看到:
- 节点 192.168.1.10:6379 负责槽 0-5460
- 节点 192.168.1.11:6379 负责槽 5461-10922
- 节点 192.168.1.12:6379 负责槽 10923-16383
这样你就能确定 某个哈希槽由哪个节点负责 了! 🚀
2. 为什么 Redis Cluster 采用 16384 个哈希槽?
Redis Cluster 选择 16384(2¹⁴) 作为固定哈希槽数量,主要有以下几个原因:
-
分片灵活,支持上百个节点
- 16384 足够大,可以支持 动态扩展到上百个节点,同时保证数据均匀分布。
-
计算效率高
CRC16(key) % 16384只需 一次取模运算,计算速度快。
-
减少元数据存储开销
- Redis Cluster 使用 Gossip 协议 进行集群管理,16384 个槽的分配信息可以高效存储和传播。
-
避免小槽过多,管理复杂
- 过多的槽会增加管理难度,而 16384 是一个合理的折中方案。
3. Redis Cluster 扩容缩容期间可以提供服务吗?
是的,Redis Cluster 在扩容/缩容过程中仍能提供服务,但可能会发生短暂的重定向。
3.1 扩容(新增节点)
当新增一个节点时,需要将部分哈希槽迁移到新节点,步骤如下:
- 将新节点加入集群。
- 使用
CLUSTER ADDSLOTS分配部分哈希槽到新节点。 - 使用
redis-cli --cluster reshard迁移数据。 - 迁移期间,客户端访问迁移中的 Key 可能会收到
ASK重定向。
3.2 缩容(移除节点)
- 先使用
redis-cli --cluster reshard将该节点的哈希槽迁移到其他节点。 - 确保该节点不再持有数据后,使用
CLUSTER FORGET将其从集群移除。
无论是扩容还是缩容,Redis Cluster 都会自动重定向客户端请求,保证集群的可用性。
4. Redis Cluster 的高可用机制
Redis Cluster 通过主从复制(Master-Slave Replication)和自动故障转移(Failover) 实现高可用。
4.1 主从架构
- 每个主节点(Master)可以有一个或多个从节点(Slave),数据会自动同步到从节点。
- 当主节点宕机时,Redis Cluster 会自动提升其中一个从节点为新的主节点。
4.2 故障检测与自动故障转移
-
故障检测:
- 每个节点会定期通过 Gossip 发送
PING,如果多个节点长时间未收到PONG,则认定目标节点故障。
- 每个节点会定期通过 Gossip 发送
-
自动选举新主节点:
- 如果主节点不可达,集群会通过 投票选举一个从节点为新的主节点,恢复服务。
-
客户端重定向:
- 如果客户端访问了宕机的主节点,会收到
MOVED指令,自动转向新主节点。
- 如果客户端访问了宕机的主节点,会收到
5. Redis Cluster 的节点通信机制
Redis Cluster 采用 Gossip 协议 进行节点通信,以保持集群状态同步。
5.1 Gossip 机制
- 每个节点定期向随机其他节点发送
PING,目标节点返回PONG,并附带自己的集群状态信息。 - 这样,所有节点都可以间接获取全网节点状态,实现快速状态传播。
5.2 重要的通信命令
-
PING/PONG(心跳检测)
PING请求集群状态,PONG反馈最新的集群信息。
-
MOVED / ASK(数据迁移时的重定向)
MOVED:告诉客户端 Key 已迁移到新节点,请求新的主节点。ASK:短暂访问目标 Key 的迁移节点,等迁移完成后才访问新主节点。
-
FAILOVER 选举
- 当主节点故障,集群会通过选举机制确定新的主节点。
5.3 端口
- 主端口(默认 6379) :处理正常的 Redis 读写请求。
- 集群总线端口(6379+10000,即 16379) :专用于 Gossip 消息交换。
6. 结论
Redis Cluster 通过 哈希槽机制 实现分片存储,使数据分布均匀,并提供动态扩展能力。
- 16384 个哈希槽 平衡了计算效率与存储灵活性。
- Gossip 协议 让集群能够快速检测故障并自动恢复。
- 高可用机制 确保 Redis 在扩容、缩容或节点故障时仍能正常运行。
这些特性使 Redis Cluster 成为 高性能、可扩展、可靠的分布式存储方案,广泛应用于缓存、消息队列、排行榜等高并发场景。