Redis从入门到精通(八、Redis 集群)

952 阅读26分钟

此篇介绍Redis Cluster 集群,简单介绍一下集群的实现,主要还是具体的实践部分:集群的开启,故障转移,添加节点,移除节点

Redis集群中的基本概念

Redis的集群模式提供了数据的分片功能,并能保证每个分片上的可用性。Redis集群每个节点需要打开2个TCP连接,一个为客户端提供服务,如 6379,另一个端口在第一个端口上 +10000,为 16379。用于集群总线,节点使用集群总线进行故障检测,配置更新,故障转移授权等。客户端不应尝试与集群总线接口进行连接。必须打开这两个端口,集群才能正常工作。(两个端口的偏移量始终是 10000)

集群中的数据分片

Redis Cluster 不使用一致性Hash,它使用的是另一种方式:hash slot(哈希槽)。

Redis集群中共有16384个Hash槽,采用了 CRC 16 & 16384 计算出hash槽的值。Redis集群的每个节点负责一部分hash槽,例如:3个节点,其中A节点(0-5500),B节点(5501-11000),C节点(11001-16383).

在添加或这删除节点时,只需要将节点上的部分槽移动到新节点上即可,例如,需要添加一个新节点D,将A,B,C上部分的槽移动到D上即可。删除节点同理,例如需要删除A,只需要将A上的槽移动到B,C上。

集群中的主从模型

为了保证集群中每个节点的可用性,cluster使用了主从模型。例如,三主三从的架构中:A,B,C,A1,B1,C1 ,A和A1为主从复制,A节点出现故障,集群将A1升为主节点,保证了集群的可用性,如果A1也出现故障,集群将不可用。

集群一致性保证

Redis Cluster 无法保证数据的强一致性。Redis的异步复制是导致无法保证数据一致的第一个原因: 客户端向A写入数据 --> A向客户端回复 --> A将数据扩散至从节点A1,A2,A3,可能在扩散的过程中出现了故障,导致数据数据丢失。可以将复制扩散设置为同步,全部写入后再向客户端返回,但是这样就导致性能过低。

网络发生分区时,客户端与少数实例隔离,也可能出现数据丢失的情况, A,A1,B,B1,C,C1,Client, client 正在向C中写入数据,出现了网络分区,导致 client 和 C 被隔离,集群选举C1成为新的主节点,网络恢复后,C中的数据将会丢失,这种情况以通过设置 node timeout 来控制数据丢失的情况。节点超时过后,主节点被视为失败,可以由其中一个副本替换。类似地,在节点超时已经过去而主节点无法感知大多数其他主节点之后,它进入错误状态并停止接受写入。

Redis 集群的一致性,基本上要在性能和y一致性之间做一个平衡。


Redis 集群配置

cluster-enabled <yes/no>
cluster-config-file <filename>
cluster-node-timeout <milliseconds>
cluster-slave-validity-factor <factor>
cluster-migration-barrier <count>
cluster-require-full-coverage <yes/no>
  • cluster-enabled <yes/no> ,是否开启集群模式,默认不开启
  • cluster-config-file <filename> ,开启集群后,Redis集群会在每次发生更改时的配置写入到文件中,在重新启动时,使用这个配置文件。这个文件一般不去认为的改动。
  • cluster-node-timeout <milliseconds>,节点超时时长,如果节点无法访问超过这个时间,从节点将会进行故障转移。
  • cluster-slave-validity-factor <factor>,如果设置为零,则从站将始终尝试对主站进行故障切换,而不管主站和从站之间的链路是否保持断开连接的时间长短。如果该值为正,则计算最大断开时间作为节点超时值乘以此选项提供的因子,如果节点是从属节点,则如果主链接断开连接的时间超过指定的时间,则不会尝试启动故障转移。例如,如果节点超时设置为5秒,并且有效性因子设置为10,则从主设备断开超过50秒的从设备将不会尝试故障转移其主设备。请注意,如果没有从站能够对其进行故障转移,则任何不同于零的值都可能导致Redis群集在主站发生故障后不可用。在这种情况下,只有当原始主服务器重新加入群集时,群集才会返回。
  • cluster-migration-barrier <count> ,主服务器将保持连接的最小从服务器数,以便另一个从服务器迁移到不再由任何从服务器覆盖的主服务器。
  • cluster-require-full-coverage <yes/no>,:如果设置为yes,则默认情况下,如果任何节点未覆盖某个百分比的key space,则集群将停止接受写入。如果该选项设置为no,即使只能处理有关键子集的请求,集群仍将提供查询。

Redis Cluster 使用

我这里使用的Redis版本为 5.0.3,不同版本可能命令会有些不同。

首先准备6个Redis节点,条件有限,就在一台服务器上进行,拷贝6份redis.conf,最基本的必须配置有:

port 7000
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
appendonly yes

6个节点的端口号为: 7000,7001,7002,7003,7004,7005

分别启动6个节点:

redis-server redis-1.conf
redis-server redis-2.conf
redis-server redis-3.conf
redis-server redis-4.conf
redis-server redis-5.conf
redis-server redis-6.conf

现在已经开启了6个节点

[root@iZnom30el3gvhxZ redis]# ps -ef | grep redis
root     16270     1  0 15:15 ?        00:00:09 redis-server *:7000 [cluster]
root     16277     1  0 15:15 ?        00:00:09 redis-server *:7001 [cluster]
root     16534     1  0 15:20 ?        00:00:08 redis-server *:7003 [cluster]
root     16541     1  0 15:20 ?        00:00:08 redis-server *:7004 [cluster]
root     16548     1  0 15:20 ?        00:00:08 redis-server *:7005 [cluster]
root     17158     1  0 15:33 ?        00:00:08 redis-server *:7002 [cluster]
root     22290 13798  0 17:17 pts/0    00:00:00 grep --color=auto redis

开启集群模式

使用下述命令创建Redis Cluster:

# 节点没有设置密码
redis-cli --cluster create 127.0.0.1:7000  127.0.0.1:7001 127.0.0.1:7002 127.0.0.1:7003 127.0.0.1:7004 127.0.0.1:7005 --cluster-replicas 1

# 节点设置了密码
redis-cli --cluster create 127.0.0.1:7000  127.0.0.1:7001 127.0.0.1:7002 127.0.0.1:7003 127.0.0.1:7004 127.0.0.1:7005 --cluster-replicas 1 -a <requirepass>

其中 --cluster-replicas 1,表示每个节点有一个从节点

需要注意的是:如果要给实例设置密码,最好所有节点的密码设置一致,并且配置 masterauth ,否则切换故障转移的时候可能会出错。也可以在开启集群时不设置密码,开启后在通过 config set masterauth abc config set requirepass abc config rewrite 命令设置。

[root@iZnom30el3gvhxZ cluster]# redis-cli --cluster create 127.0.0.1:7000  127.0.0.1:7001 127.0.0.1:7002 127.0.0.1:7003 127.0.0.1:7004 127.0.0.1:7005 --cluster-replicas 1 -a abc
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
>>> Performing hash slots allocation on 6 nodes...
Master[0] -> Slots 0 - 5460
Master[1] -> Slots 5461 - 10922
Master[2] -> Slots 10923 - 16383
Adding replica 127.0.0.1:7003 to 127.0.0.1:7000
Adding replica 127.0.0.1:7004 to 127.0.0.1:7001
Adding replica 127.0.0.1:7005 to 127.0.0.1:7002
>>> Trying to optimize slaves allocation for anti-affinity
[WARNING] Some slaves are in the same host as their master
M: 4c0b7a5b52bf3c4cb61c88f3af7fc73b8db00dea 127.0.0.1:7000
   slots:[0-5460] (5461 slots) master
M: 07bc00f5b816a612e96ad2fcdc25b4decdc498bd 127.0.0.1:7001
   slots:[5461-10922] (5462 slots) master
M: 3dc5d7b70542e56f85b0ce74190b4d37e540cdc0 127.0.0.1:7002
   slots:[10923-16383] (5461 slots) master
S: 3a5b137a1997d72cdd61fb4cf58de6530a78fbca 127.0.0.1:7003
   replicates 07bc00f5b816a612e96ad2fcdc25b4decdc498bd
S: 1793ee70d256fc3ab7ab582b20a9da0c8884e683 127.0.0.1:7004
   replicates 3dc5d7b70542e56f85b0ce74190b4d37e540cdc0
S: 08aa7f83a0e69d441f523a5b2758cf42d7b1fe6d 127.0.0.1:7005
   replicates 4c0b7a5b52bf3c4cb61c88f3af7fc73b8db00dea
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 127.0.0.1:7000)
M: 4c0b7a5b52bf3c4cb61c88f3af7fc73b8db00dea 127.0.0.1:7000
   slots:[0-5460] (5461 slots) master
   1 additional replica(s)
M: 3dc5d7b70542e56f85b0ce74190b4d37e540cdc0 127.0.0.1:7002
   slots:[10923-16383] (5461 slots) master
   1 additional replica(s)
S: 08aa7f83a0e69d441f523a5b2758cf42d7b1fe6d 127.0.0.1:7005
   slots: (0 slots) slave
   replicates 4c0b7a5b52bf3c4cb61c88f3af7fc73b8db00dea
S: 3a5b137a1997d72cdd61fb4cf58de6530a78fbca 127.0.0.1:7003
   slots: (0 slots) slave
   replicates 07bc00f5b816a612e96ad2fcdc25b4decdc498bd
S: 1793ee70d256fc3ab7ab582b20a9da0c8884e683 127.0.0.1:7004
   slots: (0 slots) slave
   replicates 3dc5d7b70542e56f85b0ce74190b4d37e540cdc0
M: 07bc00f5b816a612e96ad2fcdc25b4decdc498bd 127.0.0.1:7001
   slots:[5461-10922] (5462 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.

输入命令后,会向你确认信息,输入yes ,最后输出 [OK] All 16384 slots covered. 即为集群创建成功。

Redis 5.0 版本之后也提供了 create-clusterutils/create-cluster 也可以用这个来做集群的启动,关闭等操作。

使用 redis-cli 进入一个节点 :

[root@iZnom30el3gvhxZ cluster]# redis-cli -c -p 7000 -a abc
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
127.0.0.1:7000>

-c 为以集群模式进入,加不加这个参数的影响稍微演示,先向redis中存一个 key看看:

127.0.0.1:7000> set foo bar
-> Redirected to slot [12182] located at 127.0.0.1:7002
OK
127.0.0.1:7002>

可以看到 foo 计算出的hash slot为 12182 ,在第三个节点中,被存入到7002节点中

再来看一下如果不加 -c 是什么效果:

[root@iZnom30el3gvhxZ cluster]# redis-cli -p 7000 -a abc
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
127.0.0.1:7000> get foo
(error) MOVED 12182 127.0.0.1:7002
127.0.0.1:7000>

可以看到,抛出了一个错误 (error) MOVED 12182 127.0.0.1:7002 , 其实以集群模式进入redis-cli,也会出现这个错误,只是客户端隐藏了这个错误,并重新在7002节点上重新执行了这个操作。

在redis-cli中可以通过 cluster info 查看集群状态:

127.0.0.1:7000> CLUSTER INFO
cluster_state: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:6
cluster_my_epoch:1
cluster_stats_messages_ping_sent:1001
cluster_stats_messages_pong_sent:987
cluster_stats_messages_sent:1988
cluster_stats_messages_ping_received:982
cluster_stats_messages_pong_received:1001
cluster_stats_messages_meet_received:5
cluster_stats_messages_received:1988

cluster_state:ok 代表集群正常

测试故障转移

cluster nodes 查看集群中节点:

127.0.0.1:7000> CLUSTER NODES
4c0b7a5b52bf3c4cb61c88f3af7fc73b8db00dea 127.0.0.1:7000@17000 myself,master - 0 1557916585000 1 connected 0-5460
3dc5d7b70542e56f85b0ce74190b4d37e540cdc0 127.0.0.1:7002@17002 master - 0 1557916585000 3 connected 10923-16383
08aa7f83a0e69d441f523a5b2758cf42d7b1fe6d 127.0.0.1:7005@17005 slave 4c0b7a5b52bf3c4cb61c88f3af7fc73b8db00dea 0 1557916584562 6 connected
3a5b137a1997d72cdd61fb4cf58de6530a78fbca 127.0.0.1:7003@17003 slave 07bc00f5b816a612e96ad2fcdc25b4decdc498bd 0 1557916585565 4 connected
1793ee70d256fc3ab7ab582b20a9da0c8884e683 127.0.0.1:7004@17004 slave 3dc5d7b70542e56f85b0ce74190b4d37e540cdc0 0 1557916585966 5 connected
07bc00f5b816a612e96ad2fcdc25b4decdc498bd 127.0.0.1:7001@17001 master - 0 1557916585000 2 connected 5461-10922

关闭其中一个主节点,模拟出现故障的场景,这里关闭7000:

[root@iZnom30el3gvhxZ ~]# redis-cli -a abc -p 7000 shutdown
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
[root@iZnom30el3gvhxZ ~]# redis-cli -c -p 7001 -a abc
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
127.0.0.1:7001> CLUSTER NODES
3dc5d7b70542e56f85b0ce74190b4d37e540cdc0 127.0.0.1:7002@17002 master - 0 1557972888691 3 connected 10923-16383
1793ee70d256fc3ab7ab582b20a9da0c8884e683 127.0.0.1:7004@17004 slave 3dc5d7b70542e56f85b0ce74190b4d37e540cdc0 0 1557972889594 5 connected
07bc00f5b816a612e96ad2fcdc25b4decdc498bd 127.0.0.1:7001@17001 myself,master - 0 1557972888000 2 connected 5461-10922
4c0b7a5b52bf3c4cb61c88f3af7fc73b8db00dea 127.0.0.1:7000@17000 master,fail - 1557972867020 1557972866000 1 disconnected
08aa7f83a0e69d441f523a5b2758cf42d7b1fe6d 127.0.0.1:7005@17005 master - 0 1557972888188 7 connected 0-5460
3a5b137a1997d72cdd61fb4cf58de6530a78fbca 127.0.0.1:7003@17003 slave 07bc00f5b816a612e96ad2fcdc25b4decdc498bd 0 1557972889191 4 connected
127.0.0.1:7001>

可以看到,7000端口当前状态 fail , 原来的从节点7005变成了主节点。

再重新启动7000节点:

[root@iZnom30el3gvhxZ ~]# cd /usr/local/redis/cluster/
[root@iZnom30el3gvhxZ cluster]# redis-server cluster1/redis.conf
[root@iZnom30el3gvhxZ cluster]# redis-cli -c -p 7000 -a abc
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
127.0.0.1:7000> CLUSTER NODES
1793ee70d256fc3ab7ab582b20a9da0c8884e683 127.0.0.1:7004@17004 slave 3dc5d7b70542e56f85b0ce74190b4d37e540cdc0 0 1557973018558 5 connected
3a5b137a1997d72cdd61fb4cf58de6530a78fbca 127.0.0.1:7003@17003 slave 07bc00f5b816a612e96ad2fcdc25b4decdc498bd 0 1557973017957 4 connected
07bc00f5b816a612e96ad2fcdc25b4decdc498bd 127.0.0.1:7001@17001 master - 0 1557973018000 2 connected 5461-10922
4c0b7a5b52bf3c4cb61c88f3af7fc73b8db00dea 127.0.0.1:7000@17000 myself,slave 08aa7f83a0e69d441f523a5b2758cf42d7b1fe6d 0 1557973018000 1 connected
3dc5d7b70542e56f85b0ce74190b4d37e540cdc0 127.0.0.1:7002@17002 master - 0 1557973017556 3 connected 10923-16383
08aa7f83a0e69d441f523a5b2758cf42d7b1fe6d 127.0.0.1:7005@17005 master - 0 1557973016553 7 connected 0-5460
127.0.0.1:7000>

7000节点重新启动后变成了从节点。

手动故障转移

Redis Cluster 提供了手动执行故障转移的功能,有时候我们需要对集群中的某个几点进行维护升级等情况可能需要用到,具体指令为 CLUSTER FAILOVER,需要在想要被提升为主节点的从节点上执行

例如,7000 节点为 7005 节点的从节点,现在想对 7005 节点进行下线维护, 就需要将 7000 提升为主节点,保持对外服务器的可用性,需要在 7000 节点的客户端中执行命令:

[root@iZnom30el3gvhxZ cluster]# redis-cli -c -p 7000 -a abc
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
127.0.0.1:7000> CLUSTER FAILOVER
OK
127.0.0.1:7000> CLUSTER NODES
1793ee70d256fc3ab7ab582b20a9da0c8884e683 127.0.0.1:7004@17004 slave 3dc5d7b70542e56f85b0ce74190b4d37e540cdc0 0 1557973168583 5 connected
3a5b137a1997d72cdd61fb4cf58de6530a78fbca 127.0.0.1:7003@17003 slave 07bc00f5b816a612e96ad2fcdc25b4decdc498bd 0 1557973167380 4 connected
07bc00f5b816a612e96ad2fcdc25b4decdc498bd 127.0.0.1:7001@17001 master - 0 1557973168884 2 connected 5461-10922
4c0b7a5b52bf3c4cb61c88f3af7fc73b8db00dea 127.0.0.1:7000@17000 myself,master - 0 1557973168000 8 connected 0-5460
3dc5d7b70542e56f85b0ce74190b4d37e540cdc0 127.0.0.1:7002@17002 master - 0 1557973168583 3 connected 10923-16383
08aa7f83a0e69d441f523a5b2758cf42d7b1fe6d 127.0.0.1:7005@17005 slave 4c0b7a5b52bf3c4cb61c88f3af7fc73b8db00dea 0 1557973169385 8 connected
127.0.0.1:7000>

7005节点已经变为了从节点,可以将7005节点下线。

手动故障转移时客户端的切换是在确保新的主节点完全复制了失败的旧的主节点数据的前提下发生的,避免了数据的丢失。

添加节点

首先需要再新准备一个新的redis实例作为要添加的节点,如下,7006为新启动的节点

[root@iZnom30el3gvhxZ cluster]# ps -ef | grep redis
root      8522     1  0 10:16 ?        00:00:25 redis-server *:7000 [cluster]
root     18060     1  0 13:28 ?        00:00:00 redis-server *:7006 [cluster]
root     18066  7831  0 13:28 pts/0    00:00:00 grep --color=auto redis
root     26183     1  0 May15 ?        00:01:34 redis-server *:7001 [cluster]
root     26190     1  0 May15 ?        00:01:35 redis-server *:7002 [cluster]
root     26202     1  0 May15 ?        00:01:26 redis-server *:7003 [cluster]
root     26208     1  0 May15 ?        00:01:26 redis-server *:7004 [cluster]
root     26215     1  0 May15 ?        00:01:27 redis-server *:7005 [cluster]

添加节点的命令是 redis-cli --cluster add-node 127.0.0.1:7006 127.0.0.1:7000 , add-node 后第一个参数为新添加节点的ip,第二个为集群中任意一个节点的ip

[root@iZnom30el3gvhxZ cluster]# redis-cli --cluster add-node 127.0.0.1:7006 127.0.0.1:7000 -a wk123456
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
>>> Adding node 127.0.0.1:7006 to cluster 127.0.0.1:7000
>>> Performing Cluster Check (using node 127.0.0.1:7000)
M: 4c0b7a5b52bf3c4cb61c88f3af7fc73b8db00dea 127.0.0.1:7000
   slots:[8461-16383] (7923 slots) master
   1 additional replica(s)
S: 1793ee70d256fc3ab7ab582b20a9da0c8884e683 127.0.0.1:7004
   slots: (0 slots) slave
   replicates 3dc5d7b70542e56f85b0ce74190b4d37e540cdc0
S: 3a5b137a1997d72cdd61fb4cf58de6530a78fbca 127.0.0.1:7003
   slots: (0 slots) slave
   replicates 4c0b7a5b52bf3c4cb61c88f3af7fc73b8db00dea
M: 07bc00f5b816a612e96ad2fcdc25b4decdc498bd 127.0.0.1:7001
   slots:[0-5460] (5461 slots) master
   1 additional replica(s)
M: 3dc5d7b70542e56f85b0ce74190b4d37e540cdc0 127.0.0.1:7002
   slots:[5461-8460] (3000 slots) master
   1 additional replica(s)
S: 08aa7f83a0e69d441f523a5b2758cf42d7b1fe6d 127.0.0.1:7005
   slots: (0 slots) slave
   replicates 07bc00f5b816a612e96ad2fcdc25b4decdc498bd
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
>>> Send CLUSTER MEET to node 127.0.0.1:7006 to make it join the cluster.
[OK] New node added correctly.


127.0.0.1:7006> CLUSTER NODES
1793ee70d256fc3ab7ab582b20a9da0c8884e683 127.0.0.1:7004@17004 slave 3dc5d7b70542e56f85b0ce74190b4d37e540cdc0 0 1557985157416 12 connected
08aa7f83a0e69d441f523a5b2758cf42d7b1fe6d 127.0.0.1:7005@17005 slave 07bc00f5b816a612e96ad2fcdc25b4decdc498bd 0 1557985159418 11 connected
4c0b7a5b52bf3c4cb61c88f3af7fc73b8db00dea 127.0.0.1:7000@17000 master - 0 1557985158417 10 connected 8461-16383
07bc00f5b816a612e96ad2fcdc25b4decdc498bd 127.0.0.1:7001@17001 master - 0 1557985158000 11 connected 0-5460
3dc5d7b70542e56f85b0ce74190b4d37e540cdc0 127.0.0.1:7002@17002 master - 0 1557985158517 12 connected 5461-8460
3a5b137a1997d72cdd61fb4cf58de6530a78fbca 127.0.0.1:7003@17003 slave 4c0b7a5b52bf3c4cb61c88f3af7fc73b8db00dea 0 1557985158000 10 connected
3425f765692f0b8b9c4931c038fae8d86fe6e383 127.0.0.1:7006@17006 myself,master - 0 1557985158000 0 connected

执行完 redis-cli --cluster add-node 127.0.0.1:7006 127.0.0.1:7000 -a abc 命令后,输出 [OK] New node added correctly. ,即添加新节点成功,在 redis-cli 中,查看节点,已经被添加进去,只是7006 上没有分配hash slot,现在我们需要将其它节点上的hash slot 分配给7006节点一些(使用 reshard 命令),这里演示的是将7000节点上的节点分出4000个到7006节点上:

[root@iZnom30el3gvhxZ cluster]# redis-cli --cluster reshard 127.0.0.1:7000 -a wk123456
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
>>> Performing Cluster Check (using node 127.0.0.1:7000)
M: 4c0b7a5b52bf3c4cb61c88f3af7fc73b8db00dea 127.0.0.1:7000
   slots:[8461-16383] (7923 slots) master
   1 additional replica(s)
S: 1793ee70d256fc3ab7ab582b20a9da0c8884e683 127.0.0.1:7004
   slots: (0 slots) slave
   replicates 3dc5d7b70542e56f85b0ce74190b4d37e540cdc0
S: 3a5b137a1997d72cdd61fb4cf58de6530a78fbca 127.0.0.1:7003
   slots: (0 slots) slave
   replicates 4c0b7a5b52bf3c4cb61c88f3af7fc73b8db00dea
M: 3425f765692f0b8b9c4931c038fae8d86fe6e383 127.0.0.1:7006
   slots: (0 slots) master
M: 07bc00f5b816a612e96ad2fcdc25b4decdc498bd 127.0.0.1:7001
   slots:[0-5460] (5461 slots) master
   1 additional replica(s)
M: 3dc5d7b70542e56f85b0ce74190b4d37e540cdc0 127.0.0.1:7002
   slots:[5461-8460] (3000 slots) master
   1 additional replica(s)
S: 08aa7f83a0e69d441f523a5b2758cf42d7b1fe6d 127.0.0.1:7005
   slots: (0 slots) slave
   replicates 07bc00f5b816a612e96ad2fcdc25b4decdc498bd
[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)?

这里需要让你输入想要分配的slot数量,我们这里输入 4000,

How many slots do you want to move (from 1 to 16384)? 4000
What is the receiving node ID?

这里需要输入接收这些slot的节点,输入上述打出来的目标节点的ID即可,这里输入 3425f765692f0b8b9c4931c038fae8d86fe6e383,

How many slots do you want to move (from 1 to 16384)? 4000
What is the receiving node ID? 3425f765692f0b8b9c4931c038fae8d86fe6e383
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.
Source node #1:

这里输入源节点的id,如果是所有的节点,直接输入 all 即可,如果是一个或者多个节点,可以一个一个的输入,最后输入 done,我们这里只需要将 7000节点的上的分出来一些就行,

How many slots do you want to move (from 1 to 16384)? 4000
What is the receiving node ID? 3425f765692f0b8b9c4931c038fae8d86fe6e383
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.
Source node #1: 4c0b7a5b52bf3c4cb61c88f3af7fc73b8db00dea
Source node #2: done

还会再向你确认一遍,无误后输入 yes 等待分配完成即可。

进入 redis-cli 中查看节点:

127.0.0.1:7006> CLUSTER NODES
1793ee70d256fc3ab7ab582b20a9da0c8884e683 127.0.0.1:7004@17004 slave 3dc5d7b70542e56f85b0ce74190b4d37e540cdc0 0 1557985824187 12 connected
08aa7f83a0e69d441f523a5b2758cf42d7b1fe6d 127.0.0.1:7005@17005 slave 07bc00f5b816a612e96ad2fcdc25b4decdc498bd 0 1557985823000 11 connected
4c0b7a5b52bf3c4cb61c88f3af7fc73b8db00dea 127.0.0.1:7000@17000 master - 0 1557985823085 10 connected 12461-16383
07bc00f5b816a612e96ad2fcdc25b4decdc498bd 127.0.0.1:7001@17001 master - 0 1557985823185 11 connected 0-5460
3dc5d7b70542e56f85b0ce74190b4d37e540cdc0 127.0.0.1:7002@17002 master - 0 1557985824586 12 connected 5461-8460
3a5b137a1997d72cdd61fb4cf58de6530a78fbca 127.0.0.1:7003@17003 slave 4c0b7a5b52bf3c4cb61c88f3af7fc73b8db00dea 0 1557985823000 10 connected
3425f765692f0b8b9c4931c038fae8d86fe6e383 127.0.0.1:7006@17006 myself,master - 0 1557985824000 13 connected 8461-12460

7006上已经有了分配的slot

添加新节点为从节点

添加新节点比较简单,这里不做演示,下面贴出主要命令:

# 随机指定主服务器
redis-cli --cluster add-node 127.0.0.1:7007 127.0.0.1:7000 --cluster-slave

# 准确指定主服务器
redis-cli --cluster add-node 127.0.0.1:7007 127.0.0.1:7000 --cluster-slave --cluster-master-id 3425f765692f0b8b9c4931c038fae8d86fe6e383

redis 127.0.0.1:7007> cluster replicate 3425f765692f0b8b9c4931c038fae8d86fe6e383

移除节点

删除节点的主要命令 redis-cli --cluster del-node 127.0.0.1:7000 <node-id> del-node 后第一个参数为 集群中任意一个节点的ip,第2个参数需要移除的节点的id

需要注意的是,如果删除主节点的话,需要先将主节点中的slot分配出去,否则无法删除,如下

[root@iZnom30el3gvhxZ cluster]# redis-cli --cluster del-node 127.0.0.1:7000 3425f765692f0b8b9c4931c038fae8d86fe6e383 -a abc
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
>>> Removing node 3425f765692f0b8b9c4931c038fae8d86fe6e383 from cluster 127.0.0.1:7000
[ERR] Node 127.0.0.1:7006 is not empty! Reshard data away and try again.

执行一次 reshard 将7006上的slot 分配出去,这里不做演示,直接贴出成功删除节点的回应:

[root@iZnom30el3gvhxZ cluster]# redis-cli --cluster del-node 127.0.0.1:7000 3425f765692f0b8b9c4931c038fae8d86fe6e383 -a wk123456
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
>>> Removing node 3425f765692f0b8b9c4931c038fae8d86fe6e383 from cluster 127.0.0.1:7000
>>> Sending CLUSTER FORGET messages to the cluster...
>>> SHUTDOWN the node.
[root@iZnom30el3gvhxZ cluster]# ps -ef | grep redis
root      8522     1  0 10:16 ?        00:00:32 redis-server *:7000 [cluster]
root     19854  7831  0 14:04 pts/0    00:00:00 grep --color=auto redis
root     26183     1  0 May15 ?        00:01:40 redis-server *:7001 [cluster]
root     26190     1  0 May15 ?        00:01:40 redis-server *:7002 [cluster]
root     26202     1  0 May15 ?        00:01:29 redis-server *:7003 [cluster]
root     26208     1  0 May15 ?        00:01:28 redis-server *:7004 [cluster]
root     26215     1  0 May15 ?        00:01:29 redis-server *:7005 [cluster]

7006节点以被移除并且下线了。


更多详细资料参考:

Redis Cluster 官方文档

Redis Cluster进阶 官方文档