[toc]
| 单词 | 词性 | 音标 | 含义 |
|---|---|---|---|
| cluster | n. | /ˈklʌstə(r)/ | 集群(多节点分布式系统,自动分片 + 高可用) |
| slot | n. | /slɒt/ | 槽位(共 16384 个,key 哈希后映射到某个槽,由节点管理) |
| shard | n./v. | /ʃɑːd/ | 分片(数据按槽分布到不同节点) |
| redirect | v./n. | /ˌriːˈdaɪrekt/ | 重定向(客户端连到错误节点时,返回 MOVED 指向正确节点) |
| gossip | n./v. | /ˈɡɒsɪp/ | 八卦(集群节点间 Gossip 协议传播状态) |
| failover | n. | /ˈfeɪlˌəʊvə(r)/ | 故障转移(主节点挂,从节点自动升为主) |
| nodes | n. | /nəʊdz/ | 节点(集群中的每个 Redis 实例) |
| coverage | n. | /ˈkʌvərɪdʒ/ | 覆盖(All 16384 slots covered 表示槽分配完整、集群健康) |
Lecture11-Redis-集群
目标:搭建 Redis Cluster,理解槽(slot)分片,让数据分布到多台机器、单点故障自动转移,并让 SpringBoot 4 连接集群。
1、为什么需要集群
单机内存有限、单点风险高。集群解决两个问题:
- 水平扩容:数据分片到多台机器,突破单机内存上限。
- 高可用:每个主节点配从节点,主挂从升,自动故障转移(自带,无需哨兵)。
对比:主从+哨兵只解决高可用、不解决容量;集群既分片又高可用。
集群结构中:
- 组内是主从结构,会自动同步数据;(同构)
- 组和组之间没有数据同步机制,数据是不一样的(异构)
2、槽(slot)分片原理
Redis 为了让集群中各个主节点保存的数据尽量均衡(充分利用每一个服务器实例的资源),引入槽的概念;
Redis Cluster 把数据空间划分成 16384 个槽(slot),不管集群中主节点数量是多少,槽的个数都是固定的 16384。
也就是说,16384 个槽其实是一个『逻辑概念』,Redis 会把 16384 个槽全部映射到集群中所有主节点上。
每个 key 通过哈希映射到某个槽,槽再分配到各主节点:
key → CRC16(key) % 16384 = slot → 该 slot 所属的节点
- 3 个主节点,每个分管约 5461 个槽。
- 写一个 key 时,如果 key 的槽不在当前节点,返回 MOVED 错误并告诉你正确节点,客户端自动重定向。
- 集群模式下客户端用
-c连接,自动跟随重定向。
3、搭建 6 节点集群(3 主 3 从)
1、准备目录与 6 个配置
mkdir -p /usr/local/redis_cluster
sudo chown -R $USER:$USER redis_cluster/
cp /opt/redis-8.0.6/redis/redis.conf /usr/local/redis_cluster/
以端口 1000~6000 建 6 个实例(每个配置端口、日志、数据文件不同,另加集群开关):
# redis-cluster-1000.conf(其余改端口号即可)
include /usr/local/redis_cluster/redis.conf
port 1000
bind 0.0.0.0
protected-mode no
daemonize yes
pidfile redis1000.pid
logfile redis1000.log
dir /usr/local/redis_cluster
dbfilename dump1000.rdb
# 集群相关
cluster-enabled yes
cluster-config-file nodes-1000.conf
cluster-node-timeout 15000
appendonly yes
用
cp复制 6 份后逐份改端口,或用脚本循环生成。
2、启动 6 个实例
redis-server /usr/local/redis_cluster/redis-cluster-1000.conf
# ... 2000 ~ 6000 同样启动
启动后每个目录会生成 nodes-*.conf(记录节点 ID 和槽分配)。
3、创建集群
redis-cli --cluster create \
192.168.100.100:1000 \
192.168.100.100:2000 \
192.168.100.100:3000 \
192.168.100.100:4000 \
192.168.100.100:5000 \
192.168.100.100:6000 \
--cluster-replicas 1
--cluster-replicas 1:每个主节点配 1 个从节点。- 输入
yes确认后,集群把 16384 个槽分配给 3 个主节点,从节点自动分配。
4、验证集群
# 集群整体状态
redis-cli -c -p 1000 cluster info
# cluster_state:ok
# cluster_slots_assigned:16384
# 节点与槽分布
redis-cli -c -p 1000 cluster nodes
# 3 个 master 分别连接 0-5460 / 5461-10922 / 10923-16383
# 3 个 slave 分别 replicates 对应 master
# 健康检查
redis-cli --cluster check 192.168.100.100:1000
# [OK] All 16384 slots covered.
5、测试读写与重定向
# -c 集群模式,自动跟随 MOVED 重定向
redis-cli -c -p 1000
127.0.0.1:1000> set name tom
OK # 槽不在 1000 时,-c 会自动转到正确节点
127.0.0.1:1000> get name
"tom"
不用
-c连接时,写错节点会报MOVED错误并提示正确节点。
4、故障转移测试
# 关掉一个主节点(比如 1000)
redis-cli -p 1000 shutdown
# 等待 cluster-node-timeout 后,其从节点自动升级为新主
redis-cli -c -p 2000 cluster nodes
# 原 1000 的从节点变成 master,接管 0-5460 槽
集群自带故障转移,无需哨兵。客户端(-c / SpringBoot Lettuce)会自动感知拓扑变化。
5、对接 SpringBoot 4
spring:
data:
redis:
cluster:
nodes:
- 192.168.100.100:1000
- 192.168.100.100:2000
- 192.168.100.100:3000
max-redirects: 3 # 分片迁移时最大重定向次数
lettuce:
pool:
enabled: true
max-active: 16
max-idle: 8
cluster:
refresh:
enabled: true # 定期刷新集群拓扑
period: 60000ms
@Autowired
private StringRedisTemplate redis;
@Test
void clusterOps() {
redis.opsForValue().set("cluster:key", "cluster:value");
String v = redis.opsForValue().get("cluster:key");
}
代码与单机完全一样——
RedisTemplate自动适配集群,无需改业务代码。
6、架构对比
| 方案 | 数据分片 | 高可用 | 复杂度 | 适用 |
|---|---|---|---|---|
| 单机 | 无 | 无 | 低 | 学习/小流量 |
| 主从 + 哨兵 | 无 | 有 | 中 | 读写分离 + 高可用 |
| Redis Cluster | 有 | 有 | 高 | 大数据量 + 高可用 |
7、课堂练习
- 用脚本生成 6 个集群配置文件并启动 6 个实例。
- 用
redis-cli --cluster create ... --cluster-replicas 1创建集群。 - 用
cluster info、cluster nodes、cluster check验证集群,确认 16384 槽全覆盖。 - 关掉一个主节点,观察其从节点自动升为主;用
-c连接写入数据验证可用。 - 用 SpringBoot 4 通过
spring.data.redis.cluster.nodes连接集群读写。
8、本节验证
- 理解集群解决容量与高可用、16384 slot 分片原理 ✅
- 会搭建 6 节点集群(3 主 3 从),验证槽覆盖完整 ✅
- 会用 -c 集群模式连接,理解 MOVED 重定向 ✅
- 理解集群故障转移与架构对比,能对接 SpringBoot4 ✅