为什么要有集群?
Redis 集群(Redis Cluster)是 Redis 官方提供的分布式解决方案,用于解决单机 Redis 在数据容量、并发处理能力和高可用性上的局限。通过 Redis 集群,可以实现数据分片、故障转移和高可用性,适用于高性能和大规模数据的场景。

数据分片算法
对三种数据分片算法的介绍以及 Redis 选择哈希槽分区算法而不选其他算法的原因:
哈希求余算法
对键的哈希值进行取模运算:节点 = hash(key) % N
(N为节点数),直接决定数据存储在哪个节点。
特点
- 简单直接,实现容易。
- 节点增减时(N变化),几乎所有数据都需要重新映射。
- 扩容/缩容成本高,数据迁移量大。
一致性哈希算法
将哈希空间组织为虚拟环(0~2^32-1),节点和键都哈希映射到环上,数据存储在顺时针方向第一个节点。
特点:
- 节点增减只影响相邻节点的数据。
- 引入虚拟节点解决数据倾斜问题。
- 扩容时数据迁移量约为1/N(N为节点数)。
哈希槽分区算法
预分配固定数量的槽位(Redis为16384个),槽位均匀分配给节点,键通过CRC16(key) % 16384
确定槽位。
特点:
- 解耦数据与节点的直接关系。
- 节点增减只需迁移对应槽位的数据。
Redis选择哈希槽的核心原因:
- 扩展和缩容的平滑性:
- 与哈希求余算法相比,哈希槽分区算法在扩缩容时迁移的数据更少,保持集群的稳定性。
- 相比一致性哈希算法,哈希槽固定且简单,节点扩展只需要重新分配少量槽位即可,不需要额外的虚拟节点管理。
- 负载均衡:Redis 通过哈希槽分区实现较为均衡的数据分布,同时在实际生产环境中可以手动调整节点和哈希槽的分配,提升负载均衡效果。
- 实现复杂度:一致性哈希算法需要维护复杂的环状结构和大量的虚拟节点,而哈希槽分区算法通过预设 16384 个哈希槽,大大简化了实现和管理成本。
- 可控的迁移成本:发生主节点故障时,通过哈希槽快速找到备用节点,自动进行故障转移,并更新槽位信息,维护高可用性。
工作原理
- 读写请求处理
- 写操作只能由主节点处理,并同步到从节点。
- 读操作默认在主节点处理,可以通过配置允许从节点处理读请求,以减轻主节点压力。
- 节点通信
- Redis 集群的所有节点之间通过Gossip 协议进行通信,交换状态信息,检测节点的存活状态。
- 每个节点都会定期向其他随机节点发送 PING 消息,以检测对方是否在线。
- 如果检测到某主节点下线,Redis 会在一定条件下进行故障转移。
- 故障检测与转移
-
集群中的所有节点,都会周期性的使⽤心跳包进行通信,并对节点是否下线进行判定:
-
主观下线:节点 A 认为节点 B 不可达,但其他节点可能不同意。
-
客观下线:超过半数主节点认为节点 B 不可达,此时触发故障转移。
-
-
故障转移过程包括:
- 从节点选举新的主节点。
- 更新集群的槽信息并广播。
- 应用客户端更新主从关系。
集群扩容
添加新节点到集群,使用redis-cli添加节点:
# 添加主节点
redis-cli --cluster add-node new_host:new_port existing_host:existing_port
redis-cli --cluster
表明使用 Redis 命令行工具来操作集群。add-node
是添加节点的操作指令。new_host:new_port
代表新节点的地址和端口,也就是要加入集群的节点;existing_host:existing_port
是集群中已存在的某个节点的地址和端口,借助这个已存在的节点,新节点就能和整个集群建立联系。
# 添加从节点
redis-cli --cluster add-node new_host:new_port existing_host:existing_port --cluster-slave --cluster-master-id <master-id>
--cluster-slave
参数表明新节点要作为从节点加入集群。--cluster-master-id <master-id>
用于指定该从节点对应的主节点 ID,<master-id>
需要替换成实际的主节点 ID,这样新节点就会成为指定主节点的从节点,负责复制主节点的数据。
# 自动平衡哈希槽
redis-cli --cluster rebalance <任意集群节点IP:端口> --cluster-use-empty-masters
rebalance
指令会让集群自动调整哈希槽的分布,使各个节点的负载更均衡。<任意集群节点IP:端口>
表示可以指定集群中任意一个节点的地址和端口,命令会通过这个节点和集群通信并执行操作。--cluster-use-empty-masters
参数表示在平衡过程中会考虑使用那些没有分配哈希槽的主节点。