在前面两篇文章中,分别介绍了Redis的主从复制和哨兵模式,这篇文章我们来介绍一下Redis官方推荐的集群部署方案Redis Cluster,以及它的动态扩容、缩容过程。
Redis Cluster集群是一个由多个主从节点群组成的分布式服务器群,它具有复制、高可用和分片特性。它不需要Sentinel哨兵也能完成节点移除和故障转移的功能,并且它的性能和高可用性均优于哨兵模式,集群配置也非常简单。
在配置过程中,需要将每个节点设置成集群模式,这种集群模式没有中心节点,可水平扩展,官方文档称可以线性扩展到 1000节点。
原生搭建
首先我们采用原生搭建的方式搭建3主3从的Redis Cluster,分别给3个master节点配置一个slave节点,总计6个Redis节点。
1、修改配置文件
通用配置:
bind 0.0.0.0port 7000pidfile /var/run/redis_7000.pidlogfile "redis7000.log"dbfilename dump7000.rdbdir /home/hydra/files/redis/cluster/redis7000masterauth 123456 requirepass 123456appendonly yes appendfilename "appendonly7000.aof"
核心配置:
cluster-enabled yescluster-config-file nodes-7000.conf #这个config会保存集群配置cluster-node-timeout 15000 #超时时间cluster-replica-validity-factor 10cluster-require-full-coverage no #重要配置
修改其余5个配置文件中的端口号,然后分别启动6个Redis实例:
登陆redis-cli,使用cluster nodes 指令查看集群状态,现在集群下只存在当前一个节点:
其他5台Redis实例相同,当前仍然处于各自独立状态。
2、集群节点关联
使用meet指令进行集群下节点的关联,在7000节点上执行:
clustermeet127.0.0.17001
这样7000和7001节点就能通讯了,再执行cluster nodes,可以看见节点已经关联了。如果再关联一个节点,那么3个节点都会互相关联。继续执行:
cluster meet 127.0.0.1 7002cluster meet 127.0.0.1 7003cluster meet 127.0.0.1 7004cluster meet 127.0.0.1 7005
这样6台redis实例就全部关联起来了:
但是可以看到,当前默认全都是master节点,没有从节点,仍然不能进行写入操作。
3、指派槽位(slot)
首先尝试向节点写入值,写入失败,提示没有分配slot槽位:
这里首先解释槽位的概念,Redis集群中内置了16384个哈希槽,当需要在 Redis集群中放置一条数据时,Redis先对key使用crc16算法算出一个结果,然后把结果对16384取余,这样每个key都会对应一个编号在0-16383之间的哈希槽,Redis会根据节点数量大致均等的将哈希槽映射到不同的节点。映射流程如下图所示:
当前配置架构为3主3从形式,平均分配16384个槽位:
节点7000分配:0-5461
节点7001分配:5462-10922
节点7002分配:10923-16383
分配槽位指令:
clusteraddslotsslot#slot为槽位下标
那么在redis7000势力上就需要执行:
cluster addslots 0...cluster addslots 5461
如果要所有key值都能正常执行,需要手动执行16384次,因此创建脚本进行批量执行:
start=$1end=$2port=$3for slot in `seq ${start} ${end}`do echo "slot:${slot}" /home/hydra/files/redis/redis-5.0.4/src/redis-cli -h 127.0.0.1 -p ${port} -a 123456 cluster addslots ${slot}done
执行shell脚本:
sh addslots.sh 0 5461 7000sh addslots.sh 5462 10922 7001shaddslots.sh 10923 16383 7002
查看集群状态:
显示槽位分配成功,需要注意在Redis Cluster中,只有master主机才有槽位的概念,从机不需要分配槽位。当前我们采用的是平均分配的方式,在实际环境下,如果服务器性能有差别,可以往性能好的服务器多分配一些槽位。
4、分配主从
Redis cluster分配主从命令:
cluster replicate node-id
如果要让7003作为7000的从机,首先登录7003,执行:
cluster replicate 9d73de74af827cd5025dcd3910d8c2919d9aa24b
后面的40位id为redis7000的node-id。继续将redis7004的主机指派为redis7001,reids7005的主机指派为redis7002。查看集群状态:
其中,集群的信息会被保存到集群的配置信息会存到redis700x/node-700x.conf的配置文件中。
以集群方式运行客户端,在redis-cli加上启动参数-c:
../redis-5.0.4/src/redis-cli -h 172.16.67.134 -p 7000 -a 123456 -c
尝试写入数据,不同数据会根据槽位不同被写到不同主机上:
到这,3主3从的架构的Redis Cluster就搭建完毕了。
快速搭建
除了手动使用命令搭建Redis Cluster外,还可以使用Redis提供的内置指令来进行一键快速搭建。首先,与手动搭建相同,先修改配置文件,配置与上面完全相同,修改完成后启动。
启动完成后,使用cluster create指令进行搭建:
../redis-5.0.4/src/redis-cli --cluster create127.0.0.1:8000 127.0.0.1:8001 127.0.0.1:8002 127.0.0.1:8003127.0.0.1:8004127.0.0.1:8006--cluster-replicas1-a123456
这里的--cluster-replicas1表示1主1从架构。如果要分配为1主2从,那么就要写成:
--cluster-replicas 2
输入yes进行确认:
搭建完成,查看一下集群状态:
包括meet,槽位分配和主从分配全部自动完成。
集群扩容
1、准备新节点
新建两个redis7006,redis7007,将之前的配置文件拷过来,启动实例。这时候这两个是孤立的节点:
2、将新的主节点加入集群
使用redis-cli,语法为:
--cluster add-node
执行:
../redis-5.0.4/src/redis-cli --cluster add-node127.0.0.1:7006 127.0.0.1:7000 -a 123456
执行完成后,新节点被加入集群中:
添加完成后,默认加进来是master节点,并且没有分配槽位:
3、添加从节点,并指定它的主节点
语法:
--clusteradd-node --cluster-slave--cluster-master-idmasterID
执行:
../redis-5.0.4/src/redis-cli --cluster add-node 127.0.0.1:7007 127.0.0.1:7000 --cluster-slave --cluster-master-id edc8ff41aef320beb5081c5b50bf32485a7ffb9e -a 123456
redis7007被指定为redis7006的从节点:
查看集群状态:
4、迁移槽位和数据
语法:
/redis-cli --cluster reshard
执行:
../redis-5.0.4/src/redis-cli --clusterreshard172.16.67.134:7000 -a123456
迁移过程中,会进行询问:
How many slots do you want to move (from 1 to 16384)?
提示要分配多少槽:平均分到4个实例,所以输入4096
What is the receiving node ID?
接收节点ID:输入7006的node-id
【all/done】从哪些分配:
all,所有节点平均分配
或手动输入node-id分配,done结束
查看集群状态:
分配完成后,可以查看7006的槽位,看出3个主节点每个都给它分配了一些槽位:
0-1365
5462-6826
10923-12287
集群缩容
在集群缩容中,我们需要先删除槽位,再删除节点。如果直接删除一个主节点,那么它的从节点就会变成主节点。
1、下线迁移槽
语法:
redis-cli --cluster reshard --cluster-from 要迁出节点ID --cluster-to 接收槽节点ID --cluster-slots 迁出槽数量 已存在节点ip 端口
首先将7006的 0-1365迁移回7000,执行:
../redis-5.0.4/src/redis-cli--clusterreshard --cluster-fromedc8ff41aef320beb5081c5b50bf32485a7ffb9e --cluster-to9d73de74af827cd5025dcd3910d8c2919d9aa24b --cluster-slots1366127.0.0.17000-a12345
之后同样的方式将其余槽位迁移回redis7001和redis7002节点。执行完成后,redis7006上的槽位全部被迁移回3台主机:
2、删除节点
语法:
redis-cli --cluster del-node 已存在节点ID:端口 要删除的节点ID
先删除7006:
../redis-5.0.4/src/redis-cli --cluster del-node 127.0.0.1:7000 edc8ff41aef320beb5081c5b50bf32485a7ffb9e -a 123456
执行完成后,节点会关机,后台会直接杀死redis7006的进程。再看一下集群状态:
这时候会把redis7007分配给其他的主节点作为从节点,这是因为redis7006没有槽位和数据,因此没有发生故障转移,把redis7007升级为主节点。那么我们再看一下故障转移过程,使用kill指令杀死redis7000进程后:
redis7000变成fail状态,并且它的从机redis7003继承了它的槽位和数据。
公众号后台回复
"面试"---领取大厂面试资料
"导图"---领取24张Java后端学习笔记导图
"架构"---领取29本java架构师电子书籍
"实战"---领取springboot实战项目
"视频"---领取最新java架构师视频
"加群"---加入学习交流群
扫码关注公众号
有趣、深入、直接
与你聊聊技术
觉得有用,点个在看吧~
如果觉得《4台服务器集群搭建_Redis Cluster高可用集群搭建》对你有帮助,请点赞、收藏,并留下你的观点哦!