Docker安装Redis Cluster
5.Docker安装Redis Cluster
1. Redis集群搭建
在生产环境,Redis如果是单节点会存在单点故障,所以一般都是集群环境,所以我们一会先搭建集群,再在Redis集群环境中实现Redis缓存高级操作。
1.1 Redis集群原理

在做Redis集群前,我们先了解一下Redis集群原理:
1:无论对Redis执行增加、删除、查询操作,都会操作一个key
2:无论什么key,经过CRC16算法取模,结果都在0-16383之间,这16384个值被称为哈希槽
3:如果我们现在有一个Redis集群,集群有3个节点,会为每个节点分配一定哈希槽
RedisNode1:0-5460
RedisNode2:5461-10922
RedisNode3:10923-16383
4:每次做增加、删除、查询时,先对key进行CRC16算法取模,计算哈希槽的值
5:根据哈希槽的值重定向当前链接到指定节点上,并执行操作
Redis集群虽然能降低每个节点的载荷,但也存在宕机的风险,此时我们应该给每个节点安装一个从节点,当主节点宕机的时候,可以切换至从节点,添加从节点后,架构图如下:

1.2 Docker安装Redis集群
我们使用Docker容器安装Redis集群,准备6台机器(我们在1台机器上模拟):
| 节点 | IP | 端口 |
|---|---|---|
| RedisNode1 | 192.168.100.130 | 7001 |
| RedisNode2 | 192.168.100.130 | 7002 |
| RedisNode3 | 192.168.100.130 | 7003 |
| RedisNode4 | 192.168.100.130 | 7004 |
| RedisNode5 | 192.168.100.130 | 7005 |
| RedisNode6 | 192.168.100.130 | 7006 |
1)创建网络
创建网络(各个Redis集群节点都在同一网段下数据交换,安全性更高,传输效率也会更高):
docker network create redis-net
2)创建Redis配置
我们可以基于shell脚本批量创建每个Redis的配置文件,再采用shell脚本为脚本批量填充数据,再创建docker容器,我们可以先写一个Redis配置的模板文件redis-config.tmpl
#端口
port ${PORT}
#非保护模式
protected-mode no
#启用集群模式
cluster-enabled yes
cluster-config-file nodes.conf
#超时时间
cluster-node-timeout 5000
cluster-announce-ip 192.168.100.130
cluster-announce-port ${PORT}
cluster-announce-bus-port 1${PORT}
#开启aof持久化策略
appendonly yes
#后台运行
#daemonize yes
pidfile /var/run/redis_${PORT}.pid
3)Shell创建docker容器
我们创建一个shell脚本,从7001循环到7006,以上面的redis-config.tmpl模板为基础,批量创建每个redis节点的配置文件,并创建对应容器,文件名字叫install.sh,将改文件设置为可执行文件:
#!/bin/bash
#在/usr/local/gupao/redis-cluster下生成conf和data目标,并生成配置信息
for port in `seq 7001 7006`;
do
mkdir -p ./${port}/conf && PORT=${port} envsubst < ./redis-config.tmpl > ./${port}/conf/redis.conf && mkdir -p ./${port}/data;
done
#创建6个redis容器
for port in `seq 7001 7006`;
do
docker run -d -it -p ${port}:${port} -p 1${port}:1${port} -v /usr/local/gupao/redis-cluster/${port}/conf/redis.conf:/usr/local/etc/redis/redis.conf -v /usr/local/gupao/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;
done
#查找ip
for port in `seq 7001 7006`;
do
echo -n "$(docker inspect --format '{{ (index .NetworkSettings.Networks "redis-net").IPAddress }}' "redis-${port}")":${port}" ";
done
#换行
echo -e "\n"
#输入信息
read -p "输入要进入的Docker容器名字,默认redis-7001:" DOCKER_NAME
#判断是否为空
if [ ! $DOCKER_NAME ];
then DOCKER_NAME='redis-7001';
fi
#进入容器
docker exec -it redis-7001 /bin/bash
创建文件后执行授权:
chmod +x install.sh
此时执行./install.sh就能安装7001-7006的容器。

执行这一步之后,也只是容器安装好了,开启了集群,但哪些节点创建一个集群组还并未操作,我们需要用到redis-cli客户端工具来创建集群组:
./redis-cli --cluster create 172.20.0.2:7001 172.20.0.3:7002 172.20.0.4:7003 172.20.0.5:7004 172.20.0.6:7005 172.20.0.7:7006 --cluster-replicas 1
效果如下:

此时集群管理如下:
7001(Master) 7005(Slave)
7002(Master) 7006(Slave)
7003(Master) 7004(Slave)
关于创建集群中的相关参数我们做如下说明:
Cluster Manager Commands:
create host1:port1 ... hostN:portN #创建集群
--cluster-replicas <arg> #从节点个数
check host:port #检查集群
--cluster-search-multiple-owners #检查是否有槽同时被分配给了多个节点
info host:port #查看集群状态
fix host:port #修复集群
--cluster-search-multiple-owners #修复槽的重复分配问题
reshard host:port #指定集群的任意一节点进行迁移slot,重新分slots
--cluster-from <arg> #需要从哪些源节点上迁移slot,可从多个源节点完成迁移,以逗号隔开,传递的是节点的node id,还可以直接传递--from all,这样源节点就是集群的所有节点,不传递该参数的话,则会在迁移过程中提示用户输入
--cluster-to <arg> #slot需要迁移的目的节点的node id,目的节点只能填写一个,不传递该参数的话,则会在迁移过程中提示用户输入
--cluster-slots <arg> #需要迁移的slot数量,不传递该参数的话,则会在迁移过程中提示用户输入。
--cluster-yes #指定迁移时的确认输入
--cluster-timeout <arg> #设置migrate命令的超时时间
--cluster-pipeline <arg> #定义cluster getkeysinslot命令一次取出的key数量,不传的话使用默认值为10
--cluster-replace #是否直接replace到目标节点
rebalance host:port #指定集群的任意一节点进行平衡集群节点slot数量
--cluster-weight <node1=w1...nodeN=wN> #指定集群节点的权重
--cluster-use-empty-masters #设置可以让没有分配slot的主节点参与,默认不允许
--cluster-timeout <arg> #设置migrate命令的超时时间
--cluster-simulate #模拟rebalance操作,不会真正执行迁移操作
--cluster-pipeline <arg> #定义cluster getkeysinslot命令一次取出的key数量,默认值为10
--cluster-threshold <arg> #迁移的slot阈值超过threshold,执行rebalance操作
--cluster-replace #是否直接replace到目标节点
add-node new_host:new_port existing_host:existing_port #添加节点,把新节点加入到指定的集群,默认添加主节点
--cluster-slave #新节点作为从节点,默认随机一个主节点
--cluster-master-id <arg> #给新节点指定主节点
del-node host:port node_id #删除给定的一个节点,成功后关闭该节点服务
call host:port command arg arg .. arg #在集群的所有节点执行相关命令
set-timeout host:port milliseconds #设置cluster-node-timeout
import host:port #将外部redis数据导入集群
--cluster-from <arg> #将指定实例的数据导入到集群
--cluster-copy #migrate时指定copy
--cluster-replace #migrate时指定replace
4)集群测试
集群安装好了后,我们可以使用redis-cli进行测试:
#登录redis集群
root@6f42ad53f7bb:/usr/local/bin# ./redis-cli -p 7001 -c
#添加数据
127.0.0.1:7001> set zhangsan SDFDSFDSF.DSFSDFSDFS.FHBSDFDSFSDFF
#自动重定向到7003节点
-> Redirected to slot [12767] located at 192.168.100.130:7003
OK
192.168.100.130:7003>
5)卸载Docker容器
如果我们想卸载安装的docker容器,可以创建一个文件uninstall.sh:
#!/bin/bash
docker stop redis-7001 redis-7002 redis-7003 redis-7004 redis-7005 redis-7006
docker rm redis-7001 redis-7002 redis-7003 redis-7004 redis-7005 redis-7006
rm -rf 7001 7002 7003 7004 7005 7006
再给uninstall.sh添加可执行权限:
chmod +x uninstall.sh
执行该文件即可卸载7001-7006所有docker容器了