本文介绍Redis Cluster模式下集群的伸缩(扩容/缩容)过程进行介绍
搭建集群
利用Docker Compose搭建一个3主3从的Redis Cluster集群,docker-compose.yml文件如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99
|
version: '3.8'
services:
Redis-Service-1: image: redis:7.0 container_name: node-1 command: [ "redis-server", "/etc/redis/redis.conf" ] ports: - "6371:6379" - "16371:16379" volumes: - /Users/zgh/Docker/RedisCluster_3M3S/RedisConf/redis.conf:/etc/redis/redis.conf networks: redis_cluster_3m3s_net: ipv4_address: 120.120.120.11
Redis-Service-2: image: redis:7.0 container_name: node-2 command: [ "redis-server", "/etc/redis/redis.conf" ] ports: - "6372:6379" - "16372:16379" volumes: - /Users/zgh/Docker/RedisCluster_3M3S/RedisConf/redis.conf:/etc/redis/redis.conf networks: redis_cluster_3m3s_net: ipv4_address: 120.120.120.12
Redis-Service-3: image: redis:7.0 container_name: node-3 command: [ "redis-server", "/etc/redis/redis.conf" ] ports: - "6373:6379" - "16373:16379" volumes: - /Users/zgh/Docker/RedisCluster_3M3S/RedisConf/redis.conf:/etc/redis/redis.conf networks: redis_cluster_3m3s_net: ipv4_address: 120.120.120.13
Redis-Service-4: image: redis:7.0 container_name: node-4 command: [ "redis-server", "/etc/redis/redis.conf" ] ports: - "6374:6379" - "16374:16379" volumes: - /Users/zgh/Docker/RedisCluster_3M3S/RedisConf/redis.conf:/etc/redis/redis.conf networks: redis_cluster_3m3s_net: ipv4_address: 120.120.120.14
Redis-Service-5: image: redis:7.0 container_name: node-5 command: [ "redis-server", "/etc/redis/redis.conf" ] ports: - "6375:6379" - "16375:16379" volumes: - /Users/zgh/Docker/RedisCluster_3M3S/RedisConf/redis.conf:/etc/redis/redis.conf networks: redis_cluster_3m3s_net: ipv4_address: 120.120.120.15
Redis-Service-6: image: redis:7.0 container_name: node-6 command: [ "redis-server", "/etc/redis/redis.conf" ] ports: - "6376:6379" - "16376:16379" volumes: - /Users/zgh/Docker/RedisCluster_3M3S/RedisConf/redis.conf:/etc/redis/redis.conf networks: redis_cluster_3m3s_net: ipv4_address: 120.120.120.16
networks: redis_cluster_3m3s_net: ipam: config: - subnet: 120.120.120.0/24
|
Redis指定版本的配置文件redis.conf可通过下述链接下载对应版本的安装包后解压后获取
1
| http://download.redis.io/releases/
|
修改Redis配置文件redis.conf
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| ...
protected-mode no
port 6379
daemonize no
databases 5
masterauth "52996"
requirepass 52996
cluster-enabled yes
cluster-require-full-coverage yes
...
|
这里对于集群中的6个节点,均使用上述同一个配置文件。目录结构如下所示
现在,进行docker-compose.yml文件所在目录,利用Docker Compose命令创建容器
执行下述命令组建集群
1 2 3 4 5 6
| docker exec -it node-1 \ redis-cli -p 6379 -a 52996 --cluster create \ 120.120.120.11:6379 120.120.120.12:6379 \ 120.120.120.13:6379 120.120.120.14:6379 \ 120.120.120.15:6379 120.120.120.16:6379 \ --cluster-replicas 1
|
命令执行过程中,当分配好每个节点的槽范围后,需要输入yes进行确认,以便完成集群构建。其中,这里node 1、node 2、node 3节点为Master节点
至此这个3主3从的Redis集群就已经搭建完毕了,我们向其中添加一些数据
可通过下述命令查看集群信息
1 2 3 4 5
| redis-cli -c -p 6379 -a 52996 --cluster info 120.120.120.14:6379
cluster nodes
|
扩容
准备新节点
先期望对上述的3主3从的Redis集群进行扩容,首先Docker Compose准备3个新Redis节点——node 7、node 8、node 9。docker-compose.yml文件如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54
|
version: '3.8'
services:
Redis-Service-7: image: redis:7.0 container_name: node-7 command: [ "redis-server", "/etc/redis/redis.conf" ] ports: - "6377:6379" - "16377:16379" volumes: - /Users/zgh/Docker/RedisCluster_3M3S/RedisConf/redis.conf:/etc/redis/redis.conf networks: redis-cluster-3m3s_redis_cluster_3m3s_net: ipv4_address: 120.120.120.17
Redis-Service-8: image: redis:7.0 container_name: node-8 command: [ "redis-server", "/etc/redis/redis.conf" ] ports: - "6378:6379" - "16378:16379" volumes: - /Users/zgh/Docker/RedisCluster_3M3S/RedisConf/redis.conf:/etc/redis/redis.conf networks: redis-cluster-3m3s_redis_cluster_3m3s_net: ipv4_address: 120.120.120.18
Redis-Service-9: image: redis:7.0 container_name: node-9 command: [ "redis-server", "/etc/redis/redis.conf" ] ports: - "6379:6379" - "16379:16379" volumes: - /Users/zgh/Docker/RedisCluster_3M3S/RedisConf/redis.conf:/etc/redis/redis.conf networks: redis-cluster-3m3s_redis_cluster_3m3s_net: ipv4_address: 120.120.120.19
networks: redis-cluster-3m3s_redis_cluster_3m3s_net: external: true
|
由于需要保证3个新节点与原Redis集群在同一个网络下,可通过下述命令查看原集群所使用的完整网络名
这里对于这3个新的Redis节点,也使用上述集群的配置文件。目录结构如下所示
现在,进行新节点对应的docker-compose.yml文件所在目录,利用Docker Compose命令创建新节点容器
将新节点node 7添加集群当中并作为Master节点
这里我们通过cluster meet命令将新节点node 7添加到集群当中
1 2
| redis-cli -c -p 6379 -a 52996 cluster meet 120.120.120.17 6379
|
通过集群中节点数cluster_known_nodes值从6变为7可以看出,新节点node 7加入集群成功。虽然该新节点的角色是Master节点,但由于未分配任何槽给该节点,故cluster_size值依然为3
这里,我们期望将node 7节点作为集群中的Master节点,故利用 —cluster reshard 重分配命令实现将集群中其他Master节点的槽分配给它
1 2
| redis-cli -c -p 6379 -a 52996 --cluster reshard 120.120.120.14:6379
|
执行该命令后,会启动一个交互命令行,询问重分配操作的细节。我们需要依次输入下列信息
- 输入迁出槽位的总数。这里我们输入1000
- 输入接收槽位的节点ID。这里我们输入node 7节点的节点ID
- 确认哪些节点需要迁出槽位。这里有两种方式:依次指定需要迁出槽位的节点ID(显然需要为Master节点),最后输入done表示指定完毕;直接输入all表示从所有Mater节点中进行迁出
这里的重分配目标就是从node 1、node 3节点中将总计1000个槽位分配给node 7节点。然后其会生成相应的重分配计划,并询问是否执行。这里输入 yes 后,将会真正地执行槽迁移
从下图不难看出,node 7节点现在被分配了1000个槽位,同时node 1、node 3节点的槽位均比重分配前少了500个槽位。进一步,由于node 7节点现在已经被分配了槽,故cluster_size值由3变为4了
添加从节点到集群中
将新节点node 8作为node 7节点的从节点
现在我们将node 8节点添加集群当中。之前我们使用cluster meet命令添加节点到集群中,其实也可以使用 —cluster add-node 命令实现将新节点添加到集群当中
1 2 3
|
redis-cli -c -p 6379 -a 52996 --cluster add-node 120.120.120.18:6379 120.120.120.14:6379
|
从集群中已知节点数cluster_known_nodes从7变为8。可以看出,node 8成功加入集群且是一个Master角色
此时,我们需要将node 8设置为node 7节点的从节点
1 2 3
|
docker exec -it node-8 redis-cli -c -p 6379 -a 52996 cluster replicate <node 7节点的节点ID>
|
将新节点node 9作为node 7节点的从节点
上文当中,我们将新节点node 8作为node 7节点的从节点。实际上是分为两步完成的。先将node 8节点加入集群、再将node 8节点设置为node 7的从节点。事实上,这两个步骤可以通过一条命令直接实现。这里我们将新节点node 9作为node 7节点的从节点
1 2 3 4 5
| docker exec -it node-1 redis-cli -c -p 6379 -a 52996 --cluster add-node <新从节点IP>:<新从节点Port> <集群任意已知节点的IP>:<集群任意已知节点的Port> --cluster-slave --cluster-master-id <主节点的节点ID>
docker exec -it node-1 redis-cli -c -p 6379 -a 52996 --cluster add-node 120.120.120.19:6379 120.120.120.14:6379 --cluster-slave --cluster-master-id <node 7节点的节点ID>
|
命令执行过程,如下所示
结果如下所示,可以看到,现在node 7节点下有2个从节点——node 8、node 9
缩容
从集群中移除从节点
至此,该集群是一个4主5从的集群了。其中,node 7节点有两个从节点。现在我们期望将主节点node 7及其对应的所有从节点全部从集群中移除。将集群恢复为先前的3主3从架构。即所谓的缩容。这里我们先下线从节点——node 8、node 9,再下线主节点node 7。以避免主从间不必要的数据复制同步,下文会有对此问题的详细说明
1 2 3 4 5 6 7 8
| docker exec -it node-1 redis-cli -c -p 6379 -a 52996 --cluster del-node <节点IP>:<节点Port> <节点ID>
docker exec -it node-1 redis-cli -c -p 6379 -a 52996 --cluster del-node 120.120.120.18:6379 <node 8节点 的节点ID>
docker exec -it node-1 redis-cli -c -p 6379 -a 52996 --cluster del-node 120.120.120.19:6379 <node 9节点 的节点ID>
|
不难看出,此时,集群中不再有node 8、node 9节点。同时,node 7节点下无从节点
从集群中移除主节点
首先需要将node 7节点分配的槽位全部迁移到集群中其他节点中
故需再次使用 —cluster reshard 重分配命令
1 2
| redis-cli -c -p 6379 -a 52996 --cluster reshard 120.120.120.14:6379
|
这里我们将node 7节点的槽全部迁移到node 2节点当中。在输入迁出槽的总数时,直接输入最大值即可
然后对于重分配计划输入 yes 执行槽迁移。通过下图不难看出,重分配后,node 2节点中槽位多了1000个。同时,node 7节点也变为node 2节点的从节点了。事实上,如果我们此前未先将node 7节点下的从节点node 8、node 9从集群当中移除的话,node 8、node 9节点也将会成为node 2节点的从节点。由于最终node 8、node 9节点也需要下线,故这将会导致主从间(node 2 - node 8、node 2 - node 9)不必要的数据复制同步
现在,只需继续将node 7节点从集群中移除即可
1 2
| redis-cli -c -p 6379 -a 52996 --cluster del-node 120.120.120.17:6379 <node 7节点 的节点ID>
|
Note
在集群扩容、缩容后,各节点的槽位数量不均衡时,可利用 —cluster rebalance 命令进行重新平衡
1 2
| redis-cli -c -p 6379 -a 52996 --cluster rebalance 120.120.120.14:6379
|