Redis集群 - Cluster模式
目录
1. 自动数据分片
2. 基于Docker模拟cluster集群
3. 集群节点连接
4. 主从节点绑定
1. 自动数据分片
Cluster 集群模式采用的是去中心化拓扑结构,没有中心节点,所有节点既是存储节点,也是控制节点,在 cluster 集群里面有 16384 个哈希槽,每个 redis 节点负责一部分槽的读写操作。
每个 key 所存储的槽编号通过上式求得,然后 cluster 集群会维护一个槽位/节点映射表来记录每个槽位于那个节点之上,这样理论上可以支持水平无限扩容,解决了之前主从复制模式和哨兵机制难以在线扩容的问题
2. 基于Docker模拟cluster集群
利用 docker 模拟三主三从的 cluster 集群,在 cluster 模式里,每个节点都能进行读写操作,所以为了防止 master 节点故障导致集群不可用,需要给每个 master 节点都配置一个从节点
1) 构建三个主节点
编辑主节点的配置文件
vi /etc/master/master-1.conf
# 工作端口
port 6379
# 日志文件路径
logfile cluster-m1.log
#开启集群
cluster-enabled yes
#每个节点都有一个集群配置信息文件,由Redis自行更新
cluster-config-file nodes-6379.conf
#节点互连超时时间,毫秒为单位
cluster-node-timeout 15000
#集群所有节点状态为ok才提供服务。建议设置为no,可以在slot没有全部分配的时候提供服务
cluster-require-full-coverage no
启动第一个主节点
docker run -itd --name redis-m1 -v /etc/master:/master -p 6379:6379 redis redis-server /master/master-1.conf
查看 ip
docker inspect redis-m1 | grep IPAddress
# "IPAddress": "172.17.0.2"
编辑第二个主节点的配置文件
vi /etc/master/master-2.conf
# 工作端口
port 6380
# 日志文件路径
logfile cluster-m2.log
#开启集群
cluster-enabled yes
#每个节点都有一个集群配置信息文件,由Redis自行更新
cluster-config-file nodes-6380.conf
#节点互连超时时间,毫秒为单位
cluster-node-timeout 15000
#集群所有节点状态为ok才提供服务。建议设置为no,可以在slot没有全部分配的时候提供服务
cluster-require-full-coverage no
启动第二个主节点
docker run -itd --name redis-m2 -v /etc/master:/master -p 6380:6380 redis redis-server /master/master-2.conf
查看ip
docker inspect redis-m2 | grep IPAddress
# "IPAddress": "172.17.0.3"
编辑第三个主节点的配置文件
vi /etc/master/master-3.conf
# 工作端口
port 6381
# 日志文件路径
logfile cluster-m3.log
#开启集群
cluster-enabled yes
#每个节点都有一个集群配置信息文件,由Redis自行更新
cluster-config-file nodes-6381.conf
#节点互连超时时间,毫秒为单位
cluster-node-timeout 15000
#集群所有节点状态为ok才提供服务。建议设置为no,可以在slot没有全部分配的时候提供服务
cluster-require-full-coverage no
启动第三个主节点
docker run -itd --name redis-m3 -v /etc/master:/master -p 6381:6381 redis redis-server /master/master-3.conf
查看 ip
docker inspect redis-m3 | grep IPAddress
# "IPAddress": "172.17.0.4"
2)构建三个从节点
编辑从节点的配置文件
vi /etc/slave/slave-1.conf
# 工作端口
port 26379
# 日志文件路径
logfile cluster-s1.log
#开启集群
cluster-enabled yes
#每个节点都有一个集群配置信息文件,由Redis自行更新
cluster-config-file nodes-26379.conf
#节点互连超时时间,毫秒为单位
cluster-node-timeout 15000
#集群所有节点状态为ok才提供服务。建议设置为no,可以在slot没有全部分配的时候提供服务
cluster-require-full-coverage no
启动第一个从节点
docker run -itd --name redis-s1 -v /etc/slave:/slave -p 26379:26379 redis redis-server /slave/slave-1.conf
查看 ip
docker inspect redis-s1 | grep IPAddress
# "IPAddress": "172.17.0.5"
编辑第二个从节点的配置文件
vi /etc/slave/slave-2.conf
# 工作端口
port 26380
# 日志文件路径
logfile cluster-s2.log
#开启集群
cluster-enabled yes
#每个节点都有一个集群配置信息文件,由Redis自行更新
cluster-config-file nodes-26380.conf
#节点互连超时时间,毫秒为单位
cluster-node-timeout 15000
#集群所有节点状态为ok才提供服务。建议设置为no,可以在slot没有全部分配的时候提供服务
cluster-require-full-coverage no
启动第二个从节点
docker run -itd --name redis-s2 -v /etc/slave:/slave -p 26380:26380 redis redis-server /slave/slave-2.conf
查看 ip
docker inspect redis-s2 | grep IPAddress
# "IPAddress": "172.17.0.6"
编辑第三个从节点的配置文件
vi /etc/slave/slave-3.conf
# 工作端口
port 26381
# 日志文件路径
logfile cluster-s3.log
#开启集群
cluster-enabled yes
#每个节点都有一个集群配置信息文件,由Redis自行更新
cluster-config-file nodes-26381.conf
#节点互连超时时间,毫秒为单位
cluster-node-timeout 15000
#集群所有节点状态为ok才提供服务。建议设置为no,可以在slot没有全部分配的时候提供服务
cluster-require-full-coverage no
启动第三个从节点
docker run -itd --name redis-s3 -v /etc/slave:/slave -p 26381:26381 redis redis-server /slave/slave-3.conf
查看 ip
docker inspect redis-s3 | grep IPAddress
# "IPAddress": "172.17.0.7"
3. 集群节点连接
进入到 redis-m1 主节点
docker exec -it redis-m1 bash
将 redis-m1 节点与其他节点绑定
redis-cli -p 6379 cluster meet 172.17.0.3 6380
redis-cli -p 6379 cluster meet 172.17.0.4 6381
redis-cli -p 6379 cluster meet 172.17.0.5 26379
redis-cli -p 6379 cluster meet 172.17.0.6 26380
redis-cli -p 6379 cluster meet 172.17.0.7 26381
查看集群信息
cluster info
# 这里的status可能是fail状态,待分配哈希槽之后就是ok
编写脚本,给三个主节点 redis-m1,redis-m2,redis-m3 分配哈希槽
vi /etc/master/setHashSlot-1.sh
vi /etc/master/setHashSlot-2.sh
vi /etc/master/setHashSlot-3.sh
脚本文件
#!/bin/bash
for i in $(seq 0 5460)
do
/usr/local/bin/redis-cli -h 172.17.0.2 -p 6379 cluster addslots $i
done
#!/bin/bash
for i in $(seq 5461 10922)
do
/usr/local/bin/redis-cli -h 172.17.0.3 -p 6380 cluster addslots $i
done
#!/bin/bash
for i in $(seq 10923 16383)
do
/usr/local/bin/redis-cli -h 172.17.0.4 -p 6381 cluster addslots $i
done
在主节点各自容器内部执行脚本文件
# 在容器 redis-m1 内执行
bash /master/setHashSlot-1.sh
# 在容器 redis-m2 内执行
bash /master/setHashSlot-2.sh
# 在容器 redis-m3 内执行
bash /master/setHashSlot-3.sh
可以看到,此时集群 status=ok, 并且 cluster_known_nodes=6
4. 主从节点绑定
为每个主节点绑定一个从节点
进入主节点 redis-m1 获取每个节点的 node-id
cluster nodes
# 第一项就是每个节点的 node-id
1d08255bb1e6a5788aca0ff070f6b97b0379b3e0 172.17.0.2:6379@16379 myself,master - 0 1679981117000 1 connected 0-5460
6a81b8fe87b3c71075ce53e82fe44e709cc9db2d 172.17.0.3:6380@16380 master - 0 1679981119794 0 connected 5461-10922
33fe529a3fe2ad3240c6e538f04786963a929350 172.17.0.4:6381@16381 master - 0 1679981120797 2 connected 10923-16383
593427a1d8829fab996cd485648aabf409b546a8 172.17.0.5:26379@36379 master - 0 1679981118791 3 connected
02a8b67c56c95202d8f112f8f66ceb7d766b82b3 172.17.0.6:26380@36380 master - 0 1679981119000 4 connected
26509aa23788601e97bc5d2ebaf1785a9a6bd451 172.17.0.7:26381@36381 master - 0 1679981118000 5 connected
1)进入从节点 redis-s1,将 s1 设置为主节点 m1 的从节点
进入 redis-s1 节点
docker exec -it redis-s1 redis-cli -p 26379
执行绑定指令
cluster replicate 1d08255bb1e6a5788aca0ff070f6b97b0379b3e0
2)进入从节点 redis-s2,将 s2 设置为主节点 m2 的从节点
进入 redis-s2 节点
docker exec -it redis-s2 redis-cli -p 26380
执行绑定指令
cluster replicate 6a81b8fe87b3c71075ce53e82fe44e709cc9db2d
3)进入从节点 redis-s3,将 s3 设置为主节点 m3 的从节点
进入 redis-s3 节点
docker exec -it redis-s3 redis-cli -p 26381
执行绑定指令
cluster replicate 33fe529a3fe2ad3240c6e538f04786963a929350
这里可以看到在从节点 s3 上设置数据时,key=name 经过计算被分配到 m2 这个主节点上
加上 -c 参数表示以集群方式启动 redis,key 被自动计算并存入 m2 节点 [5798] 这个槽上
注意:单机模式下,Redis有16个数据库;集群模式下,每个 Redis 节点默认只有一个数据库db0