Redis集群的扩容与收容

Redis集群扩容

目前的redis集群上有7001、7002、7003、7004、7005、7006,六台三主三从的集群,现在要往这个集群扩容,7007,7008两个redis节点,7007作为主节点,7008作为从节点添加到集群中

  1. 基于docker安装redis编写一个安装脚本redis-port.sh
#!/bin/bash 
#在/usr/local/server/redis-cluster下生成conf和data目标,并生成配置信息 
#换行 
echo -e "\n" 

#输入信息 
read -p "请输入容器端口:" DOCKER_PORT 

#输入端口赋值 
port=$DOCKER_PORT;
echo -e "$port" 

#创建配置文件 
mkdir -p ./${port}/conf && PORT=${port} envsubst < ./redis-cluster.tmpl > ./${port}/conf/redis.conf && mkdir -p ./${port}/data; 

#创建redis容器 
docker run -d -it -p ${port}:${port} -p 1${port}:1${port} -v /usr/local/server/redis- cluster/${port}/conf/redis.conf:/usr/local/etc/redis/redis.conf -v /usr/local/server/redis- cluster/${port}/data:/data --privileged=true --restart always --name redis-${port} --net redis-net --sysctl net.core.somaxconn=1024 redis redis-server /usr/local/etc/redis/redis.conf; 

#查找ip 
echo -n "启动$(docker inspect --format '{{ (index .NetworkSettings.Networks "redis- net").IPAddress }}' "redis-${port}")":${port}" 成功!"; echo -e "\n"
  1. 添加执行权限
chmod +x redis-port.sh
  1. 执行脚本,创建redis-7007、redis-7008、redis-7009
./redis-port.sh
  1. 查看集群状态
    查看集群节点 状态
./redis-cli -p 7001 cluster nodes

Redis 集群 load lua redis 集群扩容_d3

从上图可以看出集群关系,如下

Master:7001		Slave:4
Master:7002		Slave:5
Master:7003		Slave:6
  1. 添加集群主从节点
    往集群节点中添加一个主节点,将192.168.4.11:7007节点添加到192.168.4.11:7001节点所在的集群中,并添加后作为主节点
./redis-cli --cluster add-node 192.168.4.11:7007 192.168.4.11:7001

Redis 集群 load lua redis 集群扩容_redis_02

上图可以看出7007是没有分配哈希槽的,所以我们需要重新分配哈希槽

本文末尾简单介绍一下redis分配卡槽原理

  1. 重新分配哈希槽
    将7001,7002,7003中的100个哈希槽挪给7007,命令如下
./redis-cli --cluster reshard 192.168.4.11:7001 --cluster-from 12319176fd61058316dec6eb8545bb1724afdf8a,a86d7b6ed4d3090d42e7ca5c1d1ace3e01b2ea94,0e8ca03480a6e11cbef8fb9fe07929653ee9c3ee --cluster-to dd32e4e5dc381bbf1d3cea164ef51fef724016fb --cluster-slots 100

Redis 集群 load lua redis 集群扩容_Redis 集群 load lua_03

上图可以看出,7001、7002、7003分别分给了7007,0-32(33个槽)、5461-5494(34个槽)、10923-10955(33个槽),共计100个

  1. 添加集群从节点
    集群中7007节点添加一个从节点7008,添加从节点的主要目的是提高高可用,防止主节点宕机后该节点无法提供服务,添加命令如下
./redis-cli --cluster add-node 192.168.4.11:7008 192.168.4.11:7007 --cluster-slave --cluster-master-id dd32e4e5dc381bbf1d3cea164ef51fef724016fb

Redis 集群 load lua redis 集群扩容_java_04

Redis 集群 load lua redis 集群扩容_java_05

Redis集群缩容

Redis实现缩容,需要哈希槽重新分配,将需要一处的节点所分配的所有哈希槽的值分配给其他需要运行的工作的节点上,还需要移除该节点的从节点,然后再删除该节点

  1. 移除从节点
    移除7007的从节点7008
./redis-cli --cluster del-node 192.168.4.11:7008 98622da3fd4ec079b22c3126bcca5b73ff75eb57

移除后就没有7008节点了

Redis 集群 load lua redis 集群扩容_docker_06

  1. 迁移Master的哈希槽
    我们需要将7007节点上的哈希槽迁移到7001、7002、7003节点上
    第一次迁移
./redis-cli --cluster reshard 192.168.4.11:7007 --cluster-from dd32e4e5dc381bbf1d3cea164ef51fef724016fb --cluster-to 12319176fd61058316dec6eb8545bb1724afdf8a --cluster-slots 33 --cluster-yes

迁移效果如下

Redis 集群 load lua redis 集群扩容_redis_07

第二次迁移

./redis-cli --cluster reshard 192.168.4.11:7007 --cluster-from dd32e4e5dc381bbf1d3cea164ef51fef724016fb --cluster-to a86d7b6ed4d3090d42e7ca5c1d1ace3e01b2ea94 --cluster-slots 34 --cluster-yes

第三次迁移

./redis-cli --cluster reshard 192.168.4.11:7007 --cluster-from dd32e4e5dc381bbf1d3cea164ef51fef724016fb --cluster-to 0e8ca03480a6e11cbef8fb9fe07929653ee9c3ee --cluster-slots 33 --cluster-yes

三次迁移后,集群状态查询

Redis 集群 load lua redis 集群扩容_d3_08

  1. 删除7007主节点
./redis-cli --cluster del-node 192.168.4.11:7007 dd32e4e5dc381bbf1d3cea164ef51fef724016fb

删除后集群的状态

Redis 集群 load lua redis 集群扩容_docker_09

哈希槽分配原理

Redis集群并没有使用一致性哈希,而是引入了哈希槽的概念

Redis集群又16384个哈希槽,每个Key通过CRC16校验后,对16384取模来决定放置在哪个槽,集群的每个节点负责一部分的Hash槽

Redis 集群 load lua redis 集群扩容_docker_10

CRC16算法产生的hash值有16bit,这个算法可以产生2^16=65536个值

也就是说值是分布在0~65535之间