Redis Cluster(去中心化)
1. 前情提要
在讲Redis集群架构之前,我们先简单讲下Redis单实例的架构,从最开始的一主N从,读写分离,再到Sentinel哨兵机制,单实例的Redis缓存足以应对大多数的使用场景,也能实现主从故障迁移。
但是,在某些场景下,单实例存Redis缓存会存在的几个问题:
(1)写并发:Redis单实例读写分离可以解决读操作的负载均衡,但对于写操作,仍然是全部落在了master节点上面,在海量数据高并发场景,一个节点写数据容易出现瓶颈,造成master节点的压力上升。
(2)海量数据的存储压力: 单实例Redis本质上只有一台Master作为存储,如果面对海量数据的存储,一台Redis服务器就应付不过来了,而且数据量太大意味着持久化成本高,严重时可能会阻塞服务器,造成服务请求成功率下降,降低服务的稳定性。
针对以上的问题,Redis集群提供了较为完善的方案,解决了存储能力受到单机限制,写操作无法负载均衡的问题。
2. Redis集群介绍
Redis3.0加入了Redis的集群模式,通过数据的分布式存储实现去中心化的思想。redis通过对数据进行分片,将不同的数据存储在不同的master节点上面,从而解决了海量数据的存储问题。Redis也内置了高可用机制,支持N个master节点,每个master节点都可以挂载多个slave节点,当master节点挂掉时,集群会提升它的某个slave节点作为新的master节点。
redis集群没有中心节点的说法,对于客户端来说,整个集群可以看成一个整体,可以连接任意一个节点进行操作,就像操作单一Redis实例一样,不需要任何代理中间件,当客户端操作的key没有分配到该node上时,Redis会返回转向指令,指向正确的node。
数据分布式存储
Redis 集群引入了哈希槽(slots)实现数据的分布式存储。
Redis 集群有16384个哈希槽,每个key通过CRC16校验后对16384取模来决定放置哪个槽(slot = CRC16(key)%16384)。集群的每个节点负责一部分hash槽,比如当前集群有3个节点,那么:
- 节点 A 包含 0 到 5500号哈希槽。
- 节点 B 包含5501 到 11000 号哈希槽。
- 节点 C 包含11001 到 16383号哈希槽。
这种结构很容易添加或者删除节点。比如想新添加个节点D,只需要从节点 A、B、C中得到部分哈希槽并分配到D上即可。 如果想移除节点A,需要将A中的槽移到B和C节点上,然后将没有任何槽的A节点从集群中移除即可。由于从一个节点将哈希槽移动到另一个节点并不会停止服务,所以无论添加删除或者改变某个节点的哈希槽的数量都不会造成集群不可用的状态。
3. 配置集群
3.1 环境说明
注意:本次使用三台服务器,每台服务器上运行一主一从
主机说明 | 主机IP | 端口 |
---|---|---|
master1 | 192.168.168.20 | 6379 |
slave1 | 192.168.168.20 | 6380 |
master2 | 192.168.168.21 | 6379 |
slave2 | 192.168.168.21 | 6380 |
master3 | 192.168.168.22 | 6379 |
slave3 | 192.168.168.22 | 6380 |
3.2 配置IP为20的主机
[root@master1 ~]# vim /etc/redis/redis.conf
port 6379 # 修改端口号
pidfile /var/run/redis_6379.pid # 修改pid文件名
dir /var/lib/redis # 持久化文件存放目录
dbfilename dump_6379.rdb # 修改持久化文件名,防止跟6380端口的搞混
bind 0.0.0.0 # 绑定地址
daemonize yes # 让redis后台运行
protected-mode no # 关闭保护模式
logfile /var/log/redis/redis_6379.log # 指定日志
cluster-enabled yes # 开启集群功能
cluster-config-file nodes-6379.conf #设定节点配置文件名,不需要我们创建,由redis自己维护
cluster-node-timeout 10000 # 节点心跳失败的超时时间,超过该时间(毫秒),集群自动进行主从切换
#启动第一个redis实例
[root@master1 ~]# systemctl restart redis
[root@master1 ~]# ps -ef | grep redis
redis 2016 1 0 14:50 ? 00:00:00 /usr/bin/redis-server 0.0.0.0:6379 [cluster]
root 2022 1576 0 14:51 pts/0 00:00:00 grep --color=auto redis
[root@master1 ~]# ss -lntup | grep redis
tcp LISTEN 0 511 0.0.0.0:6379 0.0.0.0:* users:(("redis-server",pid=2016,fd=6))
tcp LISTEN 0 511 0.0.0.0:16379 0.0.0.0:* users:(("redis-server",pid=2016,fd=8))
3.2.1 在该主机上配置6380端口的实例
[root@master1 ~]# cd /etc/redis/
[root@master1 redis]# ls
redis.conf redis.conf.rpmsave sentinel.conf sentinel.conf.rpmsave
[root@master1 redis]# cp redis.conf redis_6380.conf
[root@master1 redis]# sed -i 's/6379/6380/g' redis_6380.conf
[root@master1 redis]# redis-server /etc/redis/redis_6380.conf
[root@master1 redis]# ps -ef | grep redis
redis 2016 1 0 14:50 ? 00:00:00 /usr/bin/redis-server 0.0.0.0:6379 [cluster]
root 2049 1 0 14:53 ? 00:00:00 redis-server 0.0.0.0:6380 [cluster]
root 2055 1576 0 14:53 pts/0 00:00:00 grep --color=auto redis
[root@master redis]# ss -lntup | grep redis
tcp LISTEN 0 511 0.0.0.0:6380 0.0.0.0:* users:(("redis-server",pid=2049,fd=6))
tcp LISTEN 0 511 0.0.0.0:6379 0.0.0.0:* users:(("redis-server",pid=2016,fd=6))
tcp LISTEN 0 511 0.0.0.0:16380 0.0.0.0:* users:(("redis-server",pid=2049,fd=8))
tcp LISTEN 0 511 0.0.0.0:16379 0.0.0.0:* users:(("redis-server",pid=2016,fd=8))
3.3 将两个配置文件传到另外两台主机上
[root@master1 redis]# scp /etc/redis/* root@192.168.168.21:/etc/redis/
root@192.168.168.21's password:
redis_6380.conf 100% 92KB 45.6MB/s 00:00
redis.conf 100% 92KB 68.6MB/s 00:00
redis.conf.rpmsave 100% 92KB 77.4MB/s 00:00
sentinel.conf 100% 13KB 28.2MB/s 00:00
sentinel.conf.rpmsave 100% 14KB 25.2MB/s 00:00
[root@master1 redis]# scp /etc/redis/* root@192.168.168.22:/etc/redis/
root@192.168.168.22's password:
redis_6380.conf 100% 92KB 38.2MB/s 00:00
redis.conf 100% 92KB 60.4MB/s 00:00
redis.conf.rpmsave 100% 92KB 59.5MB/s 00:00
sentinel.conf 100% 13KB 19.5MB/s 00:00
sentinel.conf.rpmsave 100% 14KB 24.6MB/s 00:00
#master2上操作
[root@master2 ~]# systemctl restart redis
[root@master2 ~]# redis-server /etc/redis/redis_6380.conf
[root@master2 ~]# ps -ef | grep redis
redis 2035 1 0 14:58 ? 00:00:00 /usr/bin/redis-server 0.0.0.0:6379 [cluster]
root 2049 1 0 14:58 ? 00:00:00 redis-server 0.0.0.0:6380 [cluster]
root 2055 1391 0 14:59 pts/0 00:00:00 grep --color=auto redis
[root@slave1 ~]# ss -lntup | grep redis
tcp LISTEN 0 511 0.0.0.0:16379 0.0.0.0:* users:(("redis-server",pid=2035,fd=8))
tcp LISTEN 0 511 0.0.0.0:16380 0.0.0.0:* users:(("redis-server",pid=2049,fd=8))
tcp LISTEN 0 511 0.0.0.0:6379 0.0.0.0:* users:(("redis-server",pid=2035,fd=6))
tcp LISTEN 0 511 0.0.0.0:6380 0.0.0.0:* users:(("redis-server",pid=2049,fd=6))
#master3
[root@slave2 ~]# systemctl start redis
[root@slave2 ~]# redis-server /etc/redis/redis_6380.conf
[root@slave2 ~]# ps -ef | grep redis
redis 1899 1 0 14:59 ? 00:00:00 /usr/bin/redis-server 0.0.0.0:6379 [cluster]
root 1913 1 0 14:59 ? 00:00:00 redis-server 0.0.0.0:6380 [cluster]
root 1919 1394 0 14:59 pts/0 00:00:00 grep --color=auto redis
[root@slave2 ~]# ss -lntup | grep redis
tcp LISTEN 0 511 0.0.0.0:16380 0.0.0.0:* users:(("redis-server",pid=1913,fd=8))
tcp LISTEN 0 511 0.0.0.0:16379 0.0.0.0:* users:(("redis-server",pid=1899,fd=8))
tcp LISTEN 0 511 0.0.0.0:6380 0.0.0.0:* users:(("redis-server",pid=1913,fd=6))
tcp LISTEN 0 511 0.0.0.0:6379 0.0.0.0:* users:(("redis-server",pid=1899,fd=6))
3.4 创建集群
命令格式
redis-cli --cluster create --cluster-replicas 副本数 主机IP:端口号 主机IP:端口号
#create 创建集群
#`节点总数 ÷ (replicas + 1)` 得到的就是master的数量。节点列表中的前n个就是master,其它节点都是slave节点,随机分配到不同master。(Redis 的分配原则是:尽量保证每个主数据库运行在不同的IP地址,每个从库和主库不在一个IP地址上。)
实例
[root@master1 redis]# redis-cli --cluster create --cluster-replicas 1 192.168.168.20:6379 192.168.168.21:6379 192.168.168.22:6379 192.168.168.20:6380 192.168.168.21:6380 192.168.168.22:6380
>>> Performing hash slots allocation on 6 nodes...
Master[0] -> Slots 0 - 5460
Master[1] -> Slots 5461 - 10922
Master[2] -> Slots 10923 - 16383
Adding replica 192.168.168.21:6380 to 192.168.168.20:6379
Adding replica 192.168.168.22:6380 to 192.168.168.21:6379
Adding replica 192.168.168.20:6380 to 192.168.168.22:6379
M: bb7229c60c542180b91f115d78df950b4f867362 192.168.168.20:6379
slots:[0-5460] (5461 slots) master #主节点
M: 9bf93bbc8055d8ba2f174d76e24a3785dc04807a 192.168.168.21:6379
slots:[5461-10922] (5462 slots) master #主节点
M: b5b212faa8586e94df68a262316411e2846fc8ba 192.168.168.22:6379
slots:[10923-16383] (5461 slots) master #主节点
S: 6581159a6c4e3a2cade3914a1f63436b7e9cf80d 192.168.168.20:6380
replicates b5b212faa8586e94df68a262316411e2846fc8ba #从节点
S: 2e00da4dfa145bdabba59acd70698578cbd4bfbd 192.168.168.21:6380
replicates bb7229c60c542180b91f115d78df950b4f867362 #从节点
S: a1ca325e2bca3f197126f93bfa9aebd38c89ed45 192.168.168.22:6380
replicates 9bf93bbc8055d8ba2f174d76e24a3785dc04807a #从节点
Can I set the above configuration? (type 'yes' to accept): #输入yes
>>> Nodes configuration updated
>>> Assign a different config epoch to each node
>>> Sending CLUSTER MEET messages to join the cluster
Waiting for the cluster to join
>>> Performing Cluster Check (using node 192.168.168.20:6379)
M: bb7229c60c542180b91f115d78df950b4f867362 192.168.168.20:6379
slots:[0-5460] (5461 slots) master
1 additional replica(s)
M: b5b212faa8586e94df68a262316411e2846fc8ba 192.168.168.22:6379
slots:[10923-16383] (5461 slots) master
1 additional replica(s)
S: a1ca325e2bca3f197126f93bfa9aebd38c89ed45 192.168.168.22:6380
slots: (0 slots) slave
replicates 9bf93bbc8055d8ba2f174d76e24a3785dc04807a
M: 9bf93bbc8055d8ba2f174d76e24a3785dc04807a 192.168.168.21:6379
slots:[5461-10922] (5462 slots) master
1 additional replica(s)
S: 2e00da4dfa145bdabba59acd70698578cbd4bfbd 192.168.168.21:6380
slots: (0 slots) slave
replicates bb7229c60c542180b91f115d78df950b4f867362
S: 6581159a6c4e3a2cade3914a1f63436b7e9cf80d 192.168.168.20:6380
slots: (0 slots) slave
replicates b5b212faa8586e94df68a262316411e2846fc8ba
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
3.5 查看集群状态
[root@master1 ~]# redis-cli -p 6379 cluster nodes
#主节点
b5b212faa8586e94df68a262316411e2846fc8ba 192.168.168.22:6379@16379 master - 0 1757315334000 3 connected 10923-16383
------------------------------------------------------------------------------------
#主节点
bb7229c60c542180b91f115d78df950b4f867362 192.168.168.20:6379@16379 myself,master - 0 1757315335000 1 connected 0-5460
------------------------------------------------------------------------------------
#192.168.168.21:6379的从节点
a1ca325e2bca3f197126f93bfa9aebd38c89ed45 192.168.168.22:6380@16380 slave 9bf93bbc8055d8ba2f174d76e24a3785dc04807a 0 1757315335820 2 connected
------------------------------------------------------------------------------------
#主节点
9bf93bbc8055d8ba2f174d76e24a3785dc04807a 192.168.168.21:6379@16379 master - 0 1757315334813 2 connected 5461-10922
------------------------------------------------------------------------------------
#192.168.168.20:6379从节点
2e00da4dfa145bdabba59acd70698578cbd4bfbd 192.168.168.21:6380@16380 slave bb7229c60c542180b91f115d78df950b4f867362 0 1757315334000 1 connected
------------------------------------------------------------------------------------
#192.168.168.22:6379从节点
6581159a6c4e3a2cade3914a1f63436b7e9cf80d 192.168.168.20:6380@16380 slave b5b212faa8586e94df68a262316411e2846fc8ba 0 1757315333000 3 connected
3.6 测试
#连接集群存储数据
[root@master1 ~]# redis-cli -p 6379
[root@master1 ~]# redis-cli -p 6379
127.0.0.1:6379> set hha 123
OK
127.0.0.1:6379> set c 123
(error) MOVED 7365 192.168.168.21:6379 #结果报错
########说明######
#在集群环境下,由于 redis-cli 每次录入、查询键值时,Redis 都会计算出该 key 对应的插槽值,并交给对应插槽所在的节点进行处理。如果不是该客户端对应服务器的插槽 Redis 会报错,并告知应前往的 Redis 实例地址和端口。
##########说明结束######
#加上-c表示启用集群模式
[root@master1 ~]# redis-cli -p 6379 -c
127.0.0.1:6379> set c 123
-> Redirected to slot [7365] located at 192.168.168.21:6379
OK
192.168.168.21:6379> get c
"123"
4. 故障转移
这里我演示宕机两台的情况
4.1 模拟master1和master2宕机
#master1
[root@master1 ~]# redis-cli -p 6379 -c
127.0.0.1:6379> shutdown
not connected>
#master2
[root@master2 ~]# redis-cli -p 6379 -c
127.0.0.1:6379> shutdown
not connected>
----------------------------------------------------------------------------------------
#查看节点状态
[root@master1 ~]# redis-cli -p 6380 -c
127.0.0.1:6380> cluster nodes
#变为主节点顶替192.168.168.20:6379
2e00da4dfa145bdabba59acd70698578cbd4bfbd 192.168.168.21:6380@16380 master - 0 1757315822398 7 connected 0-5460
--------------------------------------------------------------------------------------
b5b212faa8586e94df68a262316411e2846fc8ba 192.168.168.22:6379@16379 master - 0 1757315820378 3 connected 10923-16383
------------------------------------------------------------------------------------
#变为主节点顶替192.168.168.21:6379
a1ca325e2bca3f197126f93bfa9aebd38c89ed45 192.168.168.22:6380@16380 master - 0 1757315821388 8 connected 5461-10922
--------------------------------------------------------------------------------------
#显示fail 因为把他宕机了
9bf93bbc8055d8ba2f174d76e24a3785dc04807a 192.168.168.21:6379@16379 master,fail - 1757315752653 1757315747597 2 disconnected
-----------------------------------------------------------------------------------
#宕机中
bb7229c60c542180b91f115d78df950b4f867362 192.168.168.20:6379@16379 master,fail - 1757315730474 1757315727000 1 disconnected
---------------------------------------------------------------------------------
6581159a6c4e3a2cade3914a1f63436b7e9cf80d 192.168.168.20:6380@16380 myself,slave b5b212faa8586e94df68a262316411e2846fc8ba 0 1757315819000 3 connected
127.0.0.1:6380>
4.2 恢复master1和master2
[root@master1 ~]# systemctl start redis
[root@master2 ~]# systemctl start redis
#再次查看节点状态
[root@master2 ~]# redis-cli -p 6379 -c
127.0.0.1:6379> cluster nodes
2e00da4dfa145bdabba59acd70698578cbd4bfbd 192.168.168.21:6380@16380 master - 0 1757316100620 7 connected 0-5460
-----------------------------------------------------------------------------
b5b212faa8586e94df68a262316411e2846fc8ba 192.168.168.22:6379@16379 master - 0 1757316100000 3 connected 10923-16383
-----------------------------------------------------------------------------
a1ca325e2bca3f197126f93bfa9aebd38c89ed45 192.168.168.22:6380@16380 master - 0 1757316099000 8 connected 5461-10922
-----------------------------------------------------------------------------
#192.168.168.20:6379恢复后变成了从节点
bb7229c60c542180b91f115d78df950b4f867362 192.168.168.20:6379@16379 slave 2e00da4dfa145bdabba59acd70698578cbd4bfbd 0 1757316097000 7 connected
-----------------------------------------------------------------------------
6581159a6c4e3a2cade3914a1f63436b7e9cf80d 192.168.168.20:6380@16380 slave b5b212faa8586e94df68a262316411e2846fc8ba 0 1757316100000 3 connected
-----------------------------------------------------------------------------
#192.168.168.21:6379恢复后从节点
9bf93bbc8055d8ba2f174d76e24a3785dc04807a 192.168.168.21:6379@16379 myself,slave a1ca325e2bca3f197126f93bfa9aebd38c89ed45 0 1757316096000 8 connected
补充
当发生某段插槽的主从都宕机后,如果在 redis.conf 配置文件中的 cluster-require-full-coverage 参数的值为 yes ,那么整个集群都挂掉;如果参数的值为 no ,那么该段插槽数据全都不能使用,也无法存储。
5. 集群扩容
我们向现有集群中添加两个节点,这两个节点做一主一从。主节点的端口号为 6381,从节点的端口号为 6382。
#我在master2上操作, 但是随便哪个都行。
[root@master2 redis]# cp redis.conf redis_6381.conf
[root@master2 redis]# cp redis.conf redis_6382.conf
[root@master2 redis]# sed -i 's/6379/6381/g' /etc/redis/redis_6381.conf
[root@master2 redis]# sed -i 's/6379/6382/g' /etc/redis/redis_6382.conf
[root@master2 redis]# redis-server /etc/redis/redis_6381.conf
[root@master2 redis]# redis-server /etc/redis/redis_6382.conf
[root@master2 redis]# ps -ef | grep redis
root 2049 1 0 14:58 ? 00:00:02 redis-server 0.0.0.0:6380 [cluster]
redis 2111 1 0 15:20 ? 00:00:00 /usr/bin/redis-server 0.0.0.0:6379 [cluster]
root 2169 1 0 15:27 ? 00:00:00 redis-server 0.0.0.0:6381 [cluster]
root 2175 1 0 15:27 ? 00:00:00 redis-server 0.0.0.0:6382 [cluster]
root 2181 2079 0 15:27 pts/0 00:00:00 grep --color=auto redis
[root@master2 redis]# ss -lntup | grep redis
tcp LISTEN 0 511 0.0.0.0:16379 0.0.0.0:* users:(("redis-server",pid=2111,fd=8))
tcp LISTEN 0 511 0.0.0.0:16380 0.0.0.0:* users:(("redis-server",pid=2049,fd=8))
tcp LISTEN 0 511 0.0.0.0:16381 0.0.0.0:* users:(("redis-server",pid=2169,fd=8))
tcp LISTEN 0 511 0.0.0.0:16382 0.0.0.0:* users:(("redis-server",pid=2175,fd=8))
tcp LISTEN 0 511 0.0.0.0:6379 0.0.0.0:* users:(("redis-server",pid=2111,fd=6))
tcp LISTEN 0 511 0.0.0.0:6380 0.0.0.0:* users:(("redis-server",pid=2049,fd=6))
tcp LISTEN 0 511 0.0.0.0:6381 0.0.0.0:* users:(("redis-server",pid=2169,fd=6))
tcp LISTEN 0 511 0.0.0.0:6382 0.0.0.0:* users:(("redis-server",pid=2175,fd=6))
5.1 添加节点到集群语法格式
redis-cli --cluster add-node new_host:new_port existing_host:existing_port
--cluster-slave
--cluster-master-id <arg>
add-node命令用于添加节点到集群中,参数说明如下:
- new_host:被添加节点的主机地址
- new_port:被添加节点的端口号
- existing_host:目前集群中已经存在的任一主机地址
- existing_port:目前集群中已经存在的任一端口地址
- –cluster-slave:用于添加从(Slave)节点
- –cluster-master-id:指定主(Master)节点的ID(唯一标识)字符串
5.2 添加主节点
[root@master2 ~]# redis-cli --cluster add-node 192.168.168.21:6381 192.168.168.21:6379
>>> Adding node 192.168.168.21:6381 to cluster 192.168.168.21:6379
>>> Performing Cluster Check (using node 192.168.168.21:6379)
S: 9bf93bbc8055d8ba2f174d76e24a3785dc04807a 192.168.168.21:6379
slots: (0 slots) slave
replicates a1ca325e2bca3f197126f93bfa9aebd38c89ed45
M: 2e00da4dfa145bdabba59acd70698578cbd4bfbd 192.168.168.21:6380
slots:[0-5460] (5461 slots) master
1 additional replica(s)
M: b5b212faa8586e94df68a262316411e2846fc8ba 192.168.168.22:6379
slots:[10923-16383] (5461 slots) master
1 additional replica(s)
M: a1ca325e2bca3f197126f93bfa9aebd38c89ed45 192.168.168.22:6380
slots:[5461-10922] (5462 slots) master
1 additional replica(s)
S: bb7229c60c542180b91f115d78df950b4f867362 192.168.168.20:6379
slots: (0 slots) slave
replicates 2e00da4dfa145bdabba59acd70698578cbd4bfbd
S: 6581159a6c4e3a2cade3914a1f63436b7e9cf80d 192.168.168.20:6380
slots: (0 slots) slave
replicates b5b212faa8586e94df68a262316411e2846fc8ba
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
>>> Send CLUSTER MEET to node 192.168.168.21:6381 to make it join the cluster.
[OK] New node added correctly.
5.3 添加从节点
[root@master2 ~]# redis-cli --cluster add-node 192.168.168.21:6382 192.168.168.21:6379 --cluster-slave --cluster-master-id 54c031a22586a12855fbdad2489d8e5decab3969
>>> Adding node 192.168.168.21:6382 to cluster 192.168.168.21:6379
#可以在其他主机查看192.168.168.21:6381的id
[root@master3 ~]# redis-cli -p 6379 cluster nodes
5.4 给新节点分片
分片语法
redis-cli --cluster reshard host:port
--cluster-from <arg>
--cluster-to <arg>
--cluster-slots <arg>
--cluster-yes
--cluster-timeout <arg>
--cluster-pipeline <arg>
--cluster-replace
reshard命令用于重新分片,参数说明如下:
- host:集群中已经存在的任意主机地址
- port:集群中已经存在的任意主机对应的端口号
- –cluster-from:表示slot目前所在的master节点node ID,多个ID用逗号分隔
- –cluster-to:表示需要分配节点的node ID
- –cluster-slot:分配的slot数量
- –cluster-yes:指定迁移时的确认输入
- –cluster-timeout:设置migrate命令的超时时间
- –cluster-pipeline:定义cluster getkeysinslot命令一次取出的key数量,不传的话使用默认值为10
- –cluster-replace:是否直接replace到目标节点
实例
#这里演示分500个槽,想分多少都行
[root@master2 ~]# redis-cli --cluster reshard 192.168.168.21:6379 --cluster-from 2e00da4dfa145bdabba59acd70698578cbd4bfbd --cluster-to 54c031a22586a12855fbdad2489d8e5decab3969 --cluster-slots 500 --cluster-yes --cluster-timeout 5000 --cluster-pipeline 10 --cluster-replace
查看分槽情况
[root@master2 ~]# redis-cli -p 6379
127.0.0.1:6379> cluster nodes
#刚好500个 [0-499]
54c031a22586a12855fbdad2489d8e5decab3969 192.168.168.21:6381@16381 master - 0 1757317299032 9 connected 0-499
6. 集群缩容
添加节点的时候是先添加node节点到集群,然后分配槽位,删除节点的操作与添加节点的操作正好相反,是先将被删除的Redis node上的槽位迁移到集群中的其他Redis node节点上,然后再将其删除,如果一个Redis node节点上的槽位没有被完全迁移,删除该node的时候会提示有数据且无法删除。
6.1 查看迁移点的卡槽数
#就演示刚刚添加的6381 和6380
[root@master2 ~]# redis-cli -p 6379 --cluster check 192.168.168.21:6379
#可以清楚的看到6381的卡槽数是500个
192.168.168.21:6381 (54c031a2...) -> 0 keys | 500 slots | 1 slaves.
192.168.168.21:6380 (2e00da4d...) -> 1 keys | 4961 slots | 1 slaves.
192.168.168.22:6379 (b5b212fa...) -> 0 keys | 5461 slots | 1 slaves.
192.168.168.22:6380 (a1ca325e...) -> 1 keys | 5462 slots | 1 slaves.
6.2 将迁移点的卡槽数分出去
[root@master2 ~]# redis-cli --cluster reshard 192.168.168.21:6379 --cluster-from 54c031a22586a12855fbdad2489d8e5decab3969 --cluster-to 2e00da4dfa145bdabba59acd70698578cbd4bfbd --cluster-slots 500
#可以再查看一下确认卡槽已经全部分出去了
[root@master2 ~]# redis-cli -p 6379 --cluster check 192.168.168.21:6379
192.168.168.21:6381 (54c031a2...) -> 0 keys | 0 slots | 0 slaves.
192.168.168.21:6380 (2e00da4d...) -> 1 keys | 5461 slots | 2 slaves.
192.168.168.22:6379 (b5b212fa...) -> 0 keys | 5461 slots | 1 slaves.
192.168.168.22:6380 (a1ca325e...) -> 1 keys | 5462 slots | 1 slaves.
6.3 删除节点
语法
redis-cli --cluster del-node host:port node_id
del-node命令用于从集群中删除节点,参数说明如下:
- host:集群中已经存在的主机地址
- port:集群中已经存在的主机对应的端口号
- node_id:要删除的节点ID
#要先删除从节点,然后删除主节点,否则或出现故障
[root@master2 ~]# redis-cli --cluster del-node 192.168.168.21:6382 5d72b04a154148bd2a23250ea0c8e7ebbbbcdeef
>>> Removing node 5d72b04a154148bd2a23250ea0c8e7ebbbbcdeef from cluster 192.168.168.21:6382
>>> Sending CLUSTER FORGET messages to the cluster...
>>> Sending CLUSTER RESET SOFT to the deleted node.
[root@master2 ~]# redis-cli --cluster del-node 192.168.168.21:6381 54c031a22586a12855fbdad2489d8e5decab3969
>>> Removing node 54c031a22586a12855fbdad2489d8e5decab3969 from cluster 192.168.168.21:6381
>>> Sending CLUSTER FORGET messages to the cluster...
>>> Sending CLUSTER RESET SOFT to the deleted node.
#查看一下集群,确认成功删除
[root@master2 ~]# redis-cli -p 6379
127.0.0.1:6379> cluster nodes
2e00da4dfa145bdabba59acd70698578cbd4bfbd 192.168.168.21:6380@16380 master - 0 1757318021310 10 connected 0-5460
b5b212faa8586e94df68a262316411e2846fc8ba 192.168.168.22:6379@16379 master - 0 1757318020304 3 connected 10923-16383
a1ca325e2bca3f197126f93bfa9aebd38c89ed45 192.168.168.22:6380@16380 master - 0 1757318019000 8 connected 5461-10922
bb7229c60c542180b91f115d78df950b4f867362 192.168.168.20:6379@16379 slave 2e00da4dfa145bdabba59acd70698578cbd4bfbd 0 1757318019299 10 connected
6581159a6c4e3a2cade3914a1f63436b7e9cf80d 192.168.168.20:6380@16380 slave b5b212faa8586e94df68a262316411e2846fc8ba 0 1757318019000 3 connected
9bf93bbc8055d8ba2f174d76e24a3785dc04807a 192.168.168.21:6379@16379 myself,slave a1ca325e2bca3f197126f93bfa9aebd38c89ed45 0 1757318020000 8 connected
127.0.0.1:6379>