一、Redis Cluster 分布式分片集群

Redis Cluster简介

  • Redis集群是一个可以在多个Redis节点之间进行数据共享的设施(installation)。

  • Redis集群不支持那些需要同时处理多个键的Redis命令,因为执行这些命令需要在多个Redis节点之间移动数据,并且在高负载的情况下,这些命令将降低Redis集群的性能,并导致不可预测的行为。

  • Redis集群通过分区(partition)来提供一定程度的可用性(availability):即使集群中有一部分节点失效或者无法进行通讯,集群也可以继续处理命令请求。

  • Redis集群有将数据自动切分(split)到多个节点的能力。

Redis Cluster中槽(slot)的概念

  • Redis Cluster中一共有16384个槽位,他们的编号为0、1、2、3……16382、16383,这些槽是虚拟的。

  • 这些槽位会平均分配给Redis Cluster中的每个master节点,当有某个key被映射到某个master负责的槽,那么这个master负责为这个key提供服务。

  • 当需要在redis集群中写入一个key -value的时候,会使用HASH_SLOT=CRC16(key) mod 16384之后的值,决定将key写入值哪一个槽位从而决定写入哪一个Redis节点上,从而有效解决单机瓶颈。

  • 在Redis Cluster中,只有master才拥有槽的所有权,如果是某个master的slave,这个slave只负责槽的使用,但是没有所有权。

Redis Cluster的特点

  • 解决了redis资源利用率的问题
  • 所有Redis节点使用(PING机制)互联
  • 在多分片节点中,将16384个槽位,均匀分布到多个分片节点中
  • 存数据时,将key做crc16(key),然后和16384进行取模,得出槽位值(0-16383之间)
  • 根据计算得出的槽位值,找到相对应的分片节点的主节点,存储到相应槽位上
  • 如果客户端当时连接的节点不是将来要存储的分片节点,分片集群会将客户端连接切换至真正存储节点进行数据存储
  • 在搭建集群时,会为每一个分片的主节点,对应一个从节点,实现slaveof功能,同时当主节点down,实现类似于sentinel的自动failover的功能。

Redis Cluster运行机制

  • 所有的redis节点彼此互联(PING-PONG机制),内部使用二进制协议优化传输速度和带宽。
  • 节点的fail是通过集群中超过半数的master节点检测失效时才生效。
  • 客户端与redis节点直连,不需要中间proxy层。客户端不需要连接集群所有节点,连接集群中任何一个可用节点即可。
  • redis-cluster把所有的物理节点映射到[0-16383]slot上,cluster 负责维护node<->slot<->key

Redis Cluster故障转移

  • 在集群里面,节点会对其他节点进行下线检测。
  • 当一个主节点下线时,集群里面的其他主节点负责对下线主节点进行故障移。
  • 换句话说,集群的节点集成了下线检测和故障转移等类似 Sentinel 的功能。
  • 因为 Sentinel 是一个独立运行的监控程序,而集群的下线检测和故障转移等功能是集成在节点里面的,它们的运行模式非常地不同,所以尽管这两者的功能很相似,但集群的实现没有重用 Sentinel 的代码。

 

二、Redis Cluster 分布式集群搭建

Redis Cluster 架构图:

redis-cluster-architecture.jpg

1.部署Redis Cluster

环境规划

节点 主机名 IP 端口
node1 redis-01 172.16.1.56 6379, 6380
node2 redis-02 172.16.1.57 6379, 6380
node3 redis-03 172.16.1.58 6379, 6380

创建Redis工作目录

[root@redis-01 ~]# mkdir -p /server/redis/{6379,6380}
[root@redis-02 ~]# mkdir -p /server/redis/{6379,6380}
[root@redis-03 ~]# mkdir -p /server/redis/{6379,6380}

配置每个Redis节点

  • redis-01的配置文件
#6379实例的配置文件
[root@redis-01 ~]# vim /service/redis/6379/redis.conf
bind 172.16.1.56 127.0.0.1
port 6379
daemonize yes
pidfile "/service/redis/6379/redis.pid"
loglevel notice
logfile "/service/redis/6379/redis.log"
protected-mode no
dir "/service/redis/6379"
dbfilename dump.rdb
save 900 1
save 300 10
save 60 10000
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000

#6380实例的配置文件
[root@redis-01 ~]# vim /service/redis/6380/redis.conf
bind 172.16.1.56 127.0.0.1
port 6380
daemonize yes
pidfile "/service/redis/6380/redis.pid"
loglevel notice
logfile "/service/redis/6380/redis.log"
protected-mode no
dir "/service/redis/6380"
dbfilename dump.rdb
save 900 1
save 300 10
save 60 10000
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
  • redis-02的配置文件
#6379实例的配置文件
[root@redis-02 ~]# vim /service/redis/6379/redis.conf
bind 172.16.1.57 127.0.0.1
port 6379
daemonize yes
pidfile "/service/redis/6379/redis.pid"
loglevel notice
logfile "/service/redis/6379/redis.log"
protected-mode no
dir "/service/redis/6379"
dbfilename dump.rdb
save 900 1
save 300 10
save 60 10000
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000

#6380实例的配置文件
[root@redis-02 ~]# vim /service/redis/6380/redis.conf
bind 172.16.1.57 127.0.0.1
port 6380
daemonize yes
pidfile "/service/redis/6380/redis.pid"
loglevel notice
logfile "/service/redis/6380/redis.log"
protected-mode no
dir "/service/redis/6380"
dbfilename dump.rdb
save 900 1
save 300 10
save 60 10000
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
  • redis-03的配置文件
#6379实例的配置文件
[root@redis-03 ~]# vim /service/redis/6379/redis.conf
bind 172.16.1.58 127.0.0.1
port 6379
daemonize yes
pidfile "/service/redis/6379/redis.pid"
loglevel notice
logfile "/service/redis/6379/redis.log"
protected-mode no
dir "/service/redis/6379"
dbfilename dump.rdb
save 900 1
save 300 10
save 60 10000
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000

#6380实例的配置文件
[root@redis-03 ~]# vim /service/redis/6380/redis.conf
bind 172.16.1.58 127.0.0.1
port 6380
daemonize yes
pidfile "/service/redis/6380/redis.pid"
loglevel notice
logfile "/service/redis/6380/redis.log"
protected-mode no
dir "/service/redis/6380"
dbfilename dump.rdb
save 900 1
save 300 10
save 60 10000
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000

启动每个节点的所有Redis实例

  • 启动redis服务
[root@redis-01 ~]# redis-server /server/redis/6379/redis.conf
[root@redis-02 ~]# redis-server /server/redis/6379/redis.conf
[root@redis-03 ~]# redis-server /server/redis/6379/redis.conf

[root@redis-01 ~]# redis-server /server/redis/6380/redis.conf
[root@redis-02 ~]# redis-server /server/redis/6380/redis.conf
[root@redis-03 ~]# redis-server /server/redis/6380/redis.conf
  • 查看端口,检查redis是否启动
[root@redis-01 6379]# netstat -tln | grep -Ew "6379|6380"
tcp 0 0 127.0.0.1:6379 0.0.0.0:* LISTEN
tcp 0 0 172.16.1.56:6379 0.0.0.0:* LISTEN
tcp 0 0 127.0.0.1:6380 0.0.0.0:* LISTEN
tcp 0 0 172.16.1.56:6380 0.0.0.0:* LISTEN

将所有节点加入集群

一共有node1、node2、node3这三个节点,其中每个节点有2个实例(6379、6380)。

  • 关联节点前,先查看每个redis节点信息

此时所有机器集群中都只有自己一个节点

172.16.1.56:6379> cluster nodes
98d2d1e2f97607d52585ea041db4b0e90ce06769 :6379 myself,master - 0 0 0 connected
  • 把所有节点加入集群(可以在任何一个redis实例中操作)
172.16.1.56:6379> cluster meet 172.16.1.56 6380
OK
172.16.1.56:6379> cluster meet 172.16.1.57 6379
OK
172.16.1.56:6379> cluster meet 172.16.1.57 6380
OK
172.16.1.56:6379> cluster meet 172.16.1.58 6379
OK
172.16.1.56:6379> cluster meet 172.16.1.58 6380
OK
  • 关联节点后,查看集群

所有节点都成功加入了集群中,且每个节点都是master

redis_cluster-2.png

给集群中的节点做主从

主从规划:

node1节点的6380实例作为node2节点的6379实例的从库。

node2节点的6380实例作为node3节点的6379实例的从库。

node3节点的6380实例作为node1节点的6379实例的从库。

这样任何一个节点宕机了,也能保证整个Redis Cluster 处于正常状态。

主节点:172.16.1.56:6379、172.16.1.57:6379、172.16.1.58:6379
从节点:172.16.1.56:6380、172.16.1.57:6380、172.16.1.58:6380
  • 给每个主节点分配从节点
#在redis-01上操作
[root@redis-01 ~]# redis-cli -p 6380 -h 172.16.1.56
172.16.1.56:6380> cluster replicate 6af845e7ff405845605a418f976184f343764d17
OK

#在redis-02上操作
[root@redis-02 ~]# redis-cli -p 6380 -h 172.16.1.57
172.16.1.57:6380> cluster replicate ae875d8a949e7ad62a3f5374db9de546afb6520d
OK

#在redis-03上操作
[root@redis-03 ~]# redis-cli -p 6380 -h 172.16.1.58
172.16.1.58:6380> cluster replicate 98d2d1e2f97607d52585ea041db4b0e90ce06769
OK

注意:*cluster replicate 命令后的ID是器主库的ID号*

  • 主从分配成功后,查看集群

集群中存在master和slave,说明主从分配完成。

redis_cluster-3.png

给集群分配槽位

槽位规划:

主机名 实例 槽位
redis-01 172.16.1.56:6379 0 ~ 5460
redis-02 172.16.1.57:6379 5461 ~ 10921
redis-03 172.16.1.58:6379 10922 ~ 16383
  • 执行命令,批量分配槽位
[root@redis-01 ~]# redis-cli -p 6379 -h 172.16.1.56 cluster addslots {0..5460}
OK
[root@redis-01 ~]# redis-cli -p 6379 -h 172.16.1.57 cluster addslots {5461..10921}
OK
[root@redis-01 ~]# redis-cli -p 6379 -h 172.16.1.58 cluster addslots {10922..16383}
OK

注意:槽位只分配给集群中的主节点

  • 查看槽位的分配信息

redis_cluster-4.png

  • 查看集群的状态
172.16.1.56:6379> cluster info 
cluster_state:ok #集群状态为 OK
cluster_slots_assigned:16384
cluster_slots_ok:16384
cluster_slots_pfail:0
cluster_slots_fail:0
cluster_known_nodes:6
cluster_size:3
cluster_current_epoch:5
cluster_my_epoch:3
cluster_stats_messages_sent:22785
cluster_stats_messages_received:22785

到这里,Redis Cluster 分布式集群搭建完成。

2.插入数据测试

#插入一条数据,报错
172.16.1.56:6379> set k1 v1
(error) MOVED 12706 172.16.1.58:6379 #报错:该key只能插入数据到12706槽位
#换一个值就可以插入
172.16.1.56:6379> set k2 v2
OK

#切换到槽位所在节点插入数据
[root@redis-01 ~]# redis-cli -h 172.16.1.58 -p 6379
172.16.1.58:6379> set k1 v1
OK

#使用ASK协议连接,插入数据
-c 启用群集模式(遵循-ASK和-MOVED重定向)
[root@redis-01 ~]# redis-cli -h 172.16.1.56 -p 6379 -c
172.16.1.56:6379> set k1 v1
-> Redirected to slot [12706] located at 172.16.1.58:6379
OK

#大量数据插入测试
[root@redis-01 ~]# for i in {1..10000};do redis-cli -p 6379 -h 172.16.1.56 -c set k_${i} v_${i};done

#查看数据是否平均
[root@redis-01 ~]# redis-cli -h 172.16.1.56 -p 6379
172.16.1.56:6379> dbsize
(integer) 3344
[root@redis-01 ~]# redis-cli -h 172.16.1.57 -p 6379
172.16.1.57:6379> dbsize
(integer) 3314
[root@redis-01 ~]# redis-cli -h 172.16.1.58 -p 6379
172.16.1.58:6379> dbsize
(integer) 3344

 

三、Redis Cluster 集群管理操作(核心)

1.安装集群管理插件

安装ruby插件

  • 安装ruby支持
[root@redis-01 ~]# yum install ruby rubygems -y
  • 更换gem源

查看当前的gem源

[root@redis-01 ~]# gem source -l
*** CURRENT SOURCES ***

http://rubygems.org/

添加阿里云的gem源

[root@redis-01 ~]# gem sources -a http://mirrors.aliyun.com/rubygems/
http://mirrors.aliyun.com/rubygems/ added to source

删除国外gem源

[root@redis-01 ~]# gem sources  --remove https://rubygems.org/ 
https://rubygems.org/ removed from sources

再次查看gem源,已经替换成阿里的了

[root@redis-01 ~]# gem source -l
*** CURRENT SOURCES ***

http://mirrors.aliyun.com/rubygems/
  • 使用gem安装redis的ruby插件
[root@redis-01 ~]# gem install redis -v 3.3.3
Fetching: redis-3.3.3.gem (100%)
Successfully installed redis-3.3.3
Parsing documentation for redis-3.3.3
Installing ri documentation for redis-3.3.3
1 gem installed

ruby插件使用说明

redis的ruby插件安装好后,redis就可以使用redis-trib.rb命令了。

命令参数说明:

[root@redis-01 ~]# redis-trib.rb help
create #创建集群
check #检查集群状态
info #集群信息
fix #修复集群
reshard #迁移槽位
rebalance #平衡槽位数量
add-node #添加节点
del-node #删除节点
set-timeout #设置超时时间
1call #集群中机器批量执行命令
1import #导入redis数据

2.添加新节点到Redis Cluster

在另外一台机新机器上,准备两个实例。(生产环境)

这里我就不新加服务器了,直接在redis-03上再添加2个实例( 172.16.1.58:6381172.16.1.58:6382 )。

创建实例工作目录

[root@redis-03 ~]# mkdir -p /service/redis/63{81,82}

配置两个实例

  • 实例6381的配置文件
[root@redis-03 ~]# vim /service/redis/6381/redis.conf
bind 172.16.1.58 127.0.0.1
port 6381
daemonize yes
pidfile "/service/redis/6381/redis.pid"
loglevel notice
logfile "/service/redis/6381/redis.log"
protected-mode no
dir "/service/redis/6381"
dbfilename dump.rdb
save 900 1
save 300 10
save 60 10000
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
  • 实例6382的配置文件
[root@redis-03 ~]# vim /service/redis/6382/redis.conf
bind 172.16.1.58 127.0.0.1
port 6382
daemonize yes
pidfile "/service/redis/6382/redis.pid"
loglevel notice
logfile "/service/redis/6382/redis.log"
protected-mode no
dir "/service/redis/6382"
dbfilename dump.rdb
save 900 1
save 300 10
save 60 10000
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000

启动实例

  • 启动6381和6382这2个实例
[root@redis-03 ~]# redis-server /service/redis/6381/redis.conf 
[root@redis-03 ~]# redis-server /service/redis/6382/redis.conf
  • 查看端口,检查是否启动成功
[root@redis-03 ~]# netstat -tln | grep -Ew "6381|6382"
tcp 0 0 127.0.0.1:6381 0.0.0.0:* LISTEN
tcp 0 0 172.16.1.58:6381 0.0.0.0:* LISTEN
tcp 0 0 127.0.0.1:6382 0.0.0.0:* LISTEN
tcp 0 0 172.16.1.58:6382 0.0.0.0:* LISTEN

将新节点加入到集群中

  • 添加实例到集群中
172.16.1.56:6379> cluster meet 172.16.1.58 6381
OK
172.16.1.56:6379> cluster meet 172.16.1.58 6382
OK
  • 查看集群

6381和6382这两个实例已经加入到集群中。

redis_cluster-5.png

给新添加的节点分配主从

由于原来的集群主从节点已经分配好了,现在新加入2个实例,所以这里需要稍微改动下集群中的主从规划

改动信息为:172.16.1.58:6380172.16.1.58:6381 的从库,172.16.1.58:6382172.16.1.56:6379 的从库。

  • 给172.16.1.58:6380指定新的主节点为172.16.1.58:6381
[root@redis-01 ~]# redis-cli -h 172.16.1.58 -p 6380
172.16.1.58:6380> cluster replicate fe38fef7425262fd0a98ab494d31312f4d755fc5
OK
  • 给172.16.1.58:6382指定主节点为172.16.1.56:6379
[root@redis-01 ~]# redis-cli -h 172.16.1.58 -p 6382
172.16.1.58:6382> cluster replicate 98d2d1e2f97607d52585ea041db4b0e90ce06769
OK
  • 主从配置好后,查看集群

6381和6382已经处于主从状态了

redis_cluster-6.png

重新给集群分配槽位

新节点加入集群后,发现 172.16.1.58:6381 节点并没有槽位,所以这里需要给它分配槽位。

  • 重新分片
[root@redis-01 ~]# redis-trib.rb reshard 172.16.1.58:6381
>>> Performing Cluster Check (using node 172.16.1.58:6381)
M: fe38fef7425262fd0a98ab494d31312f4d755fc5 172.16.1.58:6381
slots: (0 slots) master
1 additional replica(s)
M: 98d2d1e2f97607d52585ea041db4b0e90ce06769 172.16.1.56:6379
slots:0-5460 (5461 slots) master
1 additional replica(s)
M: ae875d8a949e7ad62a3f5374db9de546afb6520d 172.16.1.58:6379
slots:10922-16383 (5462 slots) master
1 additional replica(s)
S: b77db6765e079f5b50cbd0c168cc4d3062208b15 172.16.1.57:6380
slots: (0 slots) slave
replicates ae875d8a949e7ad62a3f5374db9de546afb6520d
S: a0e86878dc86ce6ff49aa27fa82b246adf938fd5 172.16.1.58:6382
slots: (0 slots) slave
replicates 98d2d1e2f97607d52585ea041db4b0e90ce06769
S: b91bd15633fc2b1d6d00c4d4ec405c3a9c6b5863 172.16.1.58:6380
slots: (0 slots) slave
replicates fe38fef7425262fd0a98ab494d31312f4d755fc5
S: 208c6db915517ea7424acfca94f382eb7cf254d8 172.16.1.56:6380
slots: (0 slots) slave
replicates 6af845e7ff405845605a418f976184f343764d17
M: 6af845e7ff405845605a418f976184f343764d17 172.16.1.57:6379
slots:5461-10921 (5461 slots) master
1 additional replica(s)
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
#你想要转移多少slot(槽位)到新节点
How many slots do you want to move (from 1 to 16384)? 4096
#哪个节点接收这些槽位?ID
What is the receiving node ID? fe38fef7425262fd0a98ab494d31312f4d755fc5
Please enter all the source node IDs.
Type 'all' to use all the nodes as source nodes for the hash slots.
Type 'done' once you entered all the source nodes IDs.
#哪个节点接收这些槽位?ID
Source node #1:all
#是否确认分片计划?
Do you want to proceed with the proposed reshard plan (yes/no)?yes
  • 分片完成后,检查下槽位

使用redis-trib.rb命令查看槽位

[root@redis-01 ~]# redis-trib.rb info 172.16.1.58:6381
172.16.1.58:6381 (fe38fef7...) -> 2517 keys | 4096 slots | 1 slaves.
172.16.1.56:6379 (98d2d1e2...) -> 2498 keys | 4096 slots | 1 slaves.
172.16.1.58:6379 (ae875d8a...) -> 2502 keys | 4096 slots | 1 slaves.
172.16.1.57:6379 (6af845e7...) -> 2485 keys | 4096 slots | 1 slaves.
[OK] 10002 keys in 4 masters.
0.61 keys per slot on average.

也可以通过查看集群方式查看槽位

redis_cluster-7.png

3.删除Redis Cluster中的节点

删除集群中的节点,需要移除它的槽位(如果是主节)。并重新给集群分配槽位

重新分片

[root@redis-01 ~]# redis-trib.rb reshard 172.16.1.58:6381
>>> Performing Cluster Check (using node 172.16.1.58:6381)
M: fe38fef7425262fd0a98ab494d31312f4d755fc5 172.16.1.58:6381
slots:0-1364,5461-6825,10922-12287 (4096 slots) master
1 additional replica(s)
M: 98d2d1e2f97607d52585ea041db4b0e90ce06769 172.16.1.56:6379
slots:1365-5460 (4096 slots) master
1 additional replica(s)
M: ae875d8a949e7ad62a3f5374db9de546afb6520d 172.16.1.58:6379
slots:12288-16383 (4096 slots) master
1 additional replica(s)
S: b77db6765e079f5b50cbd0c168cc4d3062208b15 172.16.1.57:6380
slots: (0 slots) slave
replicates ae875d8a949e7ad62a3f5374db9de546afb6520d
S: a0e86878dc86ce6ff49aa27fa82b246adf938fd5 172.16.1.58:6382
slots: (0 slots) slave
replicates 98d2d1e2f97607d52585ea041db4b0e90ce06769
S: b91bd15633fc2b1d6d00c4d4ec405c3a9c6b5863 172.16.1.58:6380
slots: (0 slots) slave
replicates fe38fef7425262fd0a98ab494d31312f4d755fc5
S: 208c6db915517ea7424acfca94f382eb7cf254d8 172.16.1.56:6380
slots: (0 slots) slave
replicates 6af845e7ff405845605a418f976184f343764d17
M: 6af845e7ff405845605a418f976184f343764d17 172.16.1.57:6379
slots:6826-10921 (4096 slots) master
1 additional replica(s)
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
#移动多少槽位
How many slots do you want to move (from 1 to 16384)? 4096
#接收槽位的节点ID (这里随便选择一个除6382之外的master就可以)
What is the receiving node ID? 98d2d1e2f97607d52585ea041db4b0e90ce06769
Please enter all the source node IDs.
Type 'all' to use all the nodes as source nodes for the hash slots.
Type 'done' once you entered all the source nodes IDs.
#源节点的ID (这里选择172.16.1.58:6381的ID)
Source node #1:fe38fef7425262fd0a98ab494d31312f4d755fc5
#结束
Source node #2:done
#是否确认分片计划
Do you want to proceed with the proposed reshard plan (yes/no)? yes

平衡槽位

  • 平衡前,先查看槽位信息

发现 172.16.1.58:6381 节点没有槽位

redis_cluster-8.png

查看其他节点的槽位大小,172.16.1.56:6379 最大有8192个槽位,其他两个节点都是4096个槽位。

redis_cluster-9.png

  • 使用redis-trib.rb rebalance命令给这3个节点平均分配槽位
[root@redis-01 ~]# redis-trib.rb rebalance 172.16.1.56:6379
>>> Performing Cluster Check (using node 172.16.1.56:6379)
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
>>> Rebalancing across 3 nodes. Total weight = 3
Moving 1366 slots from 172.16.1.56:6379 to 172.16.1.58:6379
############################################################################.......
Moving 1365 slots from 172.16.1.56:6379 to 172.16.1.57:6379
############################################################################.......
  • 平衡槽位后,在查看槽位大小

发现这3个主节点的槽位大小基本相等了。

redis_cluster-10.png

删除节点

先查看6381(主节点)和6382(从节点)节点的ID信息,在进行删除。

  • 查看节点状态,获取ID号

主节点:

[root@redis-01 ~]# redis-cli -p 6379 cluster nodes | grep master
fe38fef7425262fd0a98ab494d31312f4d755fc5 172.16.1.58:6381 master - 0 1594383787509 11 connected
ae875d8a949e7ad62a3f5374db9de546afb6520d 172.16.1.58:6379 master - 0 1594383788516 13 connected 0-1365 12288-16383
6af845e7ff405845605a418f976184f343764d17 172.16.1.57:6379 master - 0 1594383788516 14 connected 1366-2730 6826-10921
98d2d1e2f97607d52585ea041db4b0e90ce06769 172.16.1.56:6379 myself,master - 0 0 12 connected 2731-6825 10922-12287

从节点:

[root@redis-01 ~]# redis-cli -p 6379 cluster nodes | grep slave
a0e86878dc86ce6ff49aa27fa82b246adf938fd5 172.16.1.58:6382 slave 98d2d1e2f97607d52585ea041db4b0e90ce06769 0 1594383794053 12 connected
b91bd15633fc2b1d6d00c4d4ec405c3a9c6b5863 172.16.1.58:6380 slave 98d2d1e2f97607d52585ea041db4b0e90ce06769 0 1594383792036 12 connected
208c6db915517ea7424acfca94f382eb7cf254d8 172.16.1.56:6380 slave 6af845e7ff405845605a418f976184f343764d17 0 1594383792539 14 connected
b77db6765e079f5b50cbd0c168cc4d3062208b15 172.16.1.57:6380 slave ae875d8a949e7ad62a3f5374db9de546afb6520d 0 1594383794053 13 connected
  • 删除172.16.1.58:6381和172.16.1.58:6382两个节点
#删除主节点
[root@redis-01 ~]# redis-trib.rb del-node 172.16.1.58:6381 fe38fef7425262fd0a98ab494d31312f4d755fc5
>>> Removing node fe38fef7425262fd0a98ab494d31312f4d755fc5 from cluster 172.16.1.58:6381
>>> Sending CLUSTER FORGET messages to the cluster...
>>> SHUTDOWN the node.

#删除从节点
[root@redis-01 ~]# redis-trib.rb del-node 172.16.1.58:6382 a0e86878dc86ce6ff49aa27fa82b246adf938fd5
>>> Removing node a0e86878dc86ce6ff49aa27fa82b246adf938fd5 from cluster 172.16.1.58:6382
>>> Sending CLUSTER FORGET messages to the cluster...
>>> SHUTDOWN the node.
  • 查看集群,确认节点是否删除

发现172.16.1.58:6381和172.16.1.58:6382两个节点已经不存在于集群中了

[root@redis-01 ~]# redis-cli -p 6379 cluster nodes
ae875d8a949e7ad62a3f5374db9de546afb6520d 172.16.1.58:6379 master - 0 1594384104291 13 connected 0-1365 12288-16383
6af845e7ff405845605a418f976184f343764d17 172.16.1.57:6379 master - 0 1594384103285 14 connected 1366-2730 6826-10921
b91bd15633fc2b1d6d00c4d4ec405c3a9c6b5863 172.16.1.58:6380 slave 98d2d1e2f97607d52585ea041db4b0e90ce06769 0 1594384103788 12 connected
208c6db915517ea7424acfca94f382eb7cf254d8 172.16.1.56:6380 slave 6af845e7ff405845605a418f976184f343764d17 0 1594384102780 14 connected
b77db6765e079f5b50cbd0c168cc4d3062208b15 172.16.1.57:6380 slave ae875d8a949e7ad62a3f5374db9de546afb6520d 0 1594384102277 13 connected
98d2d1e2f97607d52585ea041db4b0e90ce06769 172.16.1.56:6379 myself,master - 0 0 12 connected 2731-6825 10922-12287

4.修复槽位分配故障

再给槽位进行重新分片时,由于意外导致分片中断,这样很可能造成槽位分配失败,集群出现故障。

模拟故障

  • 执行从新分片操作时,在输入yes后,Ctrl + c 强制终止
[root@redis-01 ~]# redis-trib.rb reshard 172.16.1.51:6379
  • 然后使用redis-trib-rb check检查集群
[root@redis-01 ~]# redis-trib.rb check 172.16.1.51:6379
>>> Check for open slots...
[WARNING] Node 172.16.1.56:6379 has slots in importing state (52).
[WARNING] Node 172.16.1.58:6379 has slots in migrating state (52).
[WARNING] The following slots are open: 52
>>> Check slots coverage...

检查后,发现52槽位出现问题。

修复故障

  • 使用redis-trib.rb fix命令修复槽位
[root@redis-01 ~]# redis-trib.rb fix 172.16.1.56:6379
  • 再次检查集群,发现故障已经被修复