此篇介绍 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-cluster
在 utils/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 进阶 官方文档