草庐IT

Docker搭建Redis Cluster集群及扩容和收容

<h1>Dvomu 2023-03-28 原文

上一篇文章讲解了Redis集群原理及搭建,由于工作中使用docker较多,本文主要讲解使用docker搭建集群及对集群的扩展收容。
环境:Centos7.6
Docker:20.10.12
Redis:6.2.6

1 集群配置

集群配置步骤

1、创建redis-cluster.tmpl配置Redis信息【端口、是否开启集群等】
2、创建redis.sh配置需要创建的redis信息
3、添加网络,redis集群使用该网络
4、执行redis.sh实现创建redis
5、执行redis-cli创建集群

1.1 安装docker

参考之前一篇文章《Docker安装及配置

1.2 脚本创建

创建目录

mkdir -p /usr/local/server/redis-cluster
cd /usr/local/server/redis-cluster
vi redis-cluster.tmpl

创建 redis-cluster.tmpl 配置Redis信息(类似redis.conf)

#端口
port ${PORT}
#非保护模式
protected-mode no
#启用集群模式
cluster-enabled yes 
cluster-config-file nodes.conf 
#超时时间
cluster-node-timeout 5000 
#集群各节点IP地址
cluster-announce-ip 192.168.88.110 
#集群节点映射端口 
cluster-announce-port ${PORT} 
#集群总线端口 
cluster-announce-bus-port 1${PORT} 
#开启aof持久化策略
appendonly yes
#后台运行
#daemonize yes
#进程号存储
pidfile /var/run/redis_${PORT}.pid 
#集群加密
#masterauth 123456
#requirepass 123456

创建redis.sh配置需要创建的 Redis 集群

#!/bin/bash 
#在/usr/local/server/redis-cluster下生成conf和data目标,并生成配置信息 
for port in `seq 7001 7006`;
do
  mkdir -p ./${port}/conf && PORT=${port} envsubst < ./redis-cluster.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/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;
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

创建 stop.sh 脚本,用于停止Redis容器,并且移除对应容器:

#!/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

1.3 增加执行权限及配置docker网络

# 配置docker网络
docker network create redis-net
# 脚本授权:给 和 添加可执行权限:
chmod +x redis.sh
chmod +x stop.sh

查看docker给每个节点分配的IP信息

docker network inspect redis-net | grep -i -E "name|ipv4address"

1.4 集群关联

执行脚本开始安装Redis节点,并进入到 /usr/local/bin 目录下执行 redis-cli 创建集群关联:
执行启动./redis.sh集群

关联集群

# 进入到任意一个安装好的redis节点的bin目录,里面有个脚本对象redis-cli,
docker exec -it redis-7001 bash
cd /usr/local/bin/
# 执行集群创建
./redis-cli --cluster create 172.18.0.2:7001 172.18.0.3:7002 172.18.0.4:7003 172.18.0.5:7004 172.18.0.6:7005 172.18.0.7:7006 --cluster-replicas 1

1.5 验证

redis-cli -p 7001 -c
cluster nodes

其他查看集群信息命令

# 查看 主节点信息
redis-cli -p 7001 cluster nodes|grep master
# 查看 从节点信息
redis-cli -p 7001 cluster nodes|grep slave
# 查看集群信息
redis-cli --cluster info ip:端口 
redis-cli --cluster check ip:端口 

2 集群扩容

上面我们搭建了集群情况如下

目前共有6个节点,3对主从,其中7001分配了5416个哈希槽,7002分配了5462个哈希槽,7003分配了5461个哈希槽。随着业务增长,我们需要增加7007和7008 2台Redis,并添加到集群中。其中7007为主节点,7008为7007的从节点,并向主节点7001和7002获取2000个哈希槽。扩容后集群信息如下图:

2.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"

添加执行权限

chmod +x redis-port.sh 

执行 redis-port.sh 脚本,实现 7007,7008节点安装。

2.2 添加集群主节点

我们需要给集群节点添加一个主节点,我们需要将 7007 节点添加到 7001 节点所在的集群中,并且添加后作为主节点,添加命令行如下:

# 将192.168.88.110:7007节点添加到192.168.88.110:7001节点所在的集群中
redis-cli --cluster add-node 192.168.88.110:7007 192.168.88.110:7001

此时我们可以进入到集群节点之一查看此时的集群状态,我们进入到7002节点中输入cluster node查询,操作方法如下

# 进入容器
docker exec -it redis-7002 /bin/bash
# 进入到redis-cli脚本目录 
cd /usr/local/bin
# 登录7002节点 
./redis-cli -p 7002 -c
# 查询集群状态
cluster nodes

哈希槽分配
从上面的集群节点信息我们可以看出一个问题,7007 节点没有分配哈希槽。因为之前3台Master已经瓜分了16384个哈希槽,所以再增加一个新节点是没有剩余哈希槽分配的,所以新增的 7007 节点没有分配到哈希槽。我们只能重新分配哈希槽,才能让新增节点分配到一定的哈希槽,重新分配哈希槽后,还要考虑之前其他Redis节点中的数据迁移。

重新分配Hash槽
我们将 7001,7002 中的 2000 个哈希槽挪给 7007 ,命令如下:

# 将7001集群中节点
#    fbc63acf974997e37a35b5ca1c71cc002ae1bb40
#    fa92c840b4a77463fb27b2b8183f144321a73f86
# 中的2000个哈希槽移动到 41eb57d0685f71aabef57908aef54189b22573b9中
redis-cli --cluster reshard 192.168.88.110:7001 --cluster-from fbc63acf974997e37a35b5ca1c71cc002ae1bb40,fa92c840b4a77463fb27b2b8183f144321a73f86 --cluster-to 41eb57d0685f71aabef57908aef54189b22573b9 --cluster-slots 2000

参数说明:
--cluster-from:表示slot目前所在的节点的node ID,多个ID用逗号分隔
--cluster-to:表示需要新分配节点的node ID
--cluster-slots:分配的slot数量

将2000个哈希槽挪给7007后,我们查询下节点信息:

redis-cli -p 7001 cluster nodes|grep master

2.3 添加集群从节点

我们需要往集群中给 7007 节点添加一个从节点 7008 ,添加从节点的主要目的是提高高可用,防止主节点宕机后该节点无法提供服务。添加从节点命令如下:

#  将192.168.88.110:7008节点添加到192.168.88.110:7007对应的集群中,并且加入的节点为从节点,
#  对应的主节点 id是41eb57d0685f71aabef57908aef54189b22573b9
redis-cli --cluster add-node 192.168.88.110:7008 192.168.88.110:7007 --cluster-slave --cluster-master-id 41eb57d0685f71aabef57908aef54189b22573b9

参数说明:
add-node: 后面的分别跟着新加入的slave和slave对应的master
cluster-slave:表示加入的是slave节点
--cluster-master-id:表示slave对应的master的node ID
执行命令后,效果如下:

2.4 验证

集群信息查看:

数据查看
到此集群热扩容已经完成,接下来对集群缩容操作。

3 集群缩容

在真实生产环境中,我们也会跟着我们的业务和环境执行缩容处理,比如双十一过后,流量没有那么大了,我们往往
会缩容处理,服务器开销。
Redis实现缩容,需要哈希槽重新分配,将需要移除的节点所分配的所有哈希槽值分配给其他需要运行工作的节点, 还需要移除该节点的从节点,然后再删除该节点。

3.1 移除从节点

移除 7007 的从节点 7008 ,命令如下:

# del-node:删除节点,后面跟着slave节点的 ip:port 和node ID
redis-cli --cluster del-node 192.168.88.110:7008 7d6948bb8b6a5ff49f26aef2ebdb400bc3dc7062

3.2 迁移Master7007的Slot

我们需要将7007节点的哈希槽迁移到7001,7002,7003节点上,仍然用上面用过的redis-cli --cluster reshard ...
语法,迁移计划:500个slots给7001,700个slots给7002,剩余800个给7003 命令如下:

# 将192.168.88.110:7007节点所在集群中41eb57d0685f71aabef57908aef54189b22573b9 节点的500个哈希槽迁移给 # fbc63acf974997e37a35b5ca1c71cc002ae1bb40节点,不回显需要迁移的slot,直接迁移。
# 第一次迁移500到7001
redis-cli --cluster reshard 192.168.88.110:7007 --cluster-from 41eb57d0685f71aabef57908aef54189b22573b9 --cluster-to fbc63acf974997e37a35b5ca1c71cc002ae1bb40 --cluster-slots 500 --cluster-yes

# 第二次迁移700到7002
redis-cli --cluster reshard 192.168.88.110:7007 --cluster-from 41eb57d0685f71aabef57908aef54189b22573b9 --cluster-to fa92c840b4a77463fb27b2b8183f144321a73f86 --cluster-slots 700 --cluster-yes

# 第三次迁移800到7003
redis-cli --cluster reshard 192.168.88.110:7007 --cluster-from 41eb57d0685f71aabef57908aef54189b22573b9 --cluster-to 05e9c301a25041ca780f369974764636513e8767 --cluster-slots 800 --cluster-yes

查看集群状态

3.3 删除7007主节点

删除节点命令如下:

redis-cli --cluster del-node 192.168.88.110:7007 41eb57d0685f71aabef57908aef54189b22573b9

集群节点查看:

到此集群的缩容完成

有关Docker搭建Redis Cluster集群及扩容和收容的更多相关文章

  1. Get https://registry-1.docker.io/v2/: net/http: request canceled while waiting - 2

    1.错误信息:Errorresponsefromdaemon:Gethttps://registry-1.docker.io/v2/:net/http:requestcanceledwhilewaitingforconnection(Client.Timeoutexceededwhileawaitingheaders)或者:Errorresponsefromdaemon:Gethttps://registry-1.docker.io/v2/:net/http:TLShandshaketimeout2.报错原因:docker使用的镜像网址默认为国外,下载容易超时,需要修改成国内镜像地址(首先阿里

  2. ruby-on-rails - 私有(private) gem 没有安装在 docker 中 - 2

    我正在尝试使用docker运行一个Rails应用程序。通过github的sshurl安装的gem很少,如下所示:Gemfilegem'swagger-docs',:git=>'git@github.com:xyz/swagger-docs.git',:branch=>'my_branch'我在docker中添加了keys,它能够克隆所需的repo并从git安装gem。DockerfileRUNmkdir-p/root/.sshCOPY./id_rsa/root/.ssh/id_rsaRUNchmod700/root/.ssh/id_rsaRUNssh-keygen-f/root/.ss

  3. ruby-on-rails - 将 Heroku 环境变量传输到 Docker 实例 - 2

    我在Heroku上构建了一个必须在Docker容器内运行的RoR应用程序。为此,我使用officialDockerfile.因为它在Heroku中很常见,所以我需要一些附加组件才能使这个应用程序完全运行。在生产中,变量DATABASE_URL在我的应用程序中可用。但是,如果我尝试其他一些使用环境变量(在我的例子中是Mailtrap)的加载项,变量不会在运行时复制到实例中。所以我的问题很简单:如何让docker实例在Heroku上执行时知道环境变量?您可能会问,我已经知道我们可以在docker-compose.yml中指定一个environment指令。我想避免这种情况,以便能够通过项目

  4. ruby - 更新 gem 时 Docker 包安装缓存问题 - 2

    我在开发和生产中都使用docker,真正困扰我的一件事是docker缓存的简单性。我的ruby​​应用程序需要bundleinstall来安装依赖项,因此我从以下Dockerfile开始:添加GemfileGemfile添加Gemfile.lockGemfile.lock运行bundleinstall--path/root/bundle所有依赖项都被缓存,并且在我添加新gem之前效果很好。即使我添加的gem只有0.5MB,从头开始安装所有应用程序gem仍然需要10-15分钟。由于依赖项文件夹的大小(大约300MB),然后再花10分钟来部署它。我在node_modules和npm上遇到了

  5. 【详解】Docker安装Elasticsearch7.16.1集群 - 2

    开门见山|拉取镜像dockerpullelasticsearch:7.16.1|配置存放的目录#存放配置文件的文件夹mkdir-p/opt/docker/elasticsearch/node-1/config#存放数据的文件夹mkdir-p/opt/docker/elasticsearch/node-1/data#存放运行日志的文件夹mkdir-p/opt/docker/elasticsearch/node-1/log#存放IK分词插件的文件夹mkdir-p/opt/docker/elasticsearch/node-1/plugins若你使用了moba,直接右键新建即可如上图所示依次类推创建

  6. 转转测试环境docker化实践 - 2

        测试环境对于任何一个软件公司来讲,都是核心基础组件之一。转转的测试环境伴随着转转的发展也从单一的几套环境发展成现在的任意的docker动态环境+docker稳定环境环境体系。期间环境系统不断的演进,去适应转转集群扩张、新业务的扩展,走了一些弯路,但最终我们将系统升级到了我们认为的终极方案。下面我们介绍一下转转环境的演进和最终的解决方案。1测试环境演进1.1单体环境    转转在2017年成立之初,5台64G内存的机器,搭建5个完整的测试环境。就满足了转转的日常所需。一台分给开发,几台分给测试。通过沟通协调就能解决多分支并行开发下冲突问题。1.2动态环境+稳定环境    随着微服务化的进

  7. 关于ES集群信息的一些查看 - 2

    文章目录查看ES信息查看节点信息查看分片信息实际场景下ES分片及副本数量应该怎么分关于ES的灵活使用查看ES信息查看版本kibana:GET/查看节点信息GET/_cat/nodes?v解释:ip:集群中节点的ip地址;heap.percent:堆内存的占用百分比;ram.percent:总内存的占用百分比,其实这个不是很准确,因为buff/cache和available也被当作使用内存;cpu:cpu占用百分比;load_1m:1分钟内cpu负载;load_5m:5分钟内cpu负载;load_15m:15分钟内cpu负载;node.role:上图的dilmrt代表全部权限master:*代表

  8. linux查看es节点使用情况,elasticsearch(es) 如何查看当前集群中哪个节点是主节点(master) - 2

    elasticsearch查看当前集群中的master节点是哪个需要使用_cat监控命令,具体如下。查看方法es主节点确定命令,以kibana上查看示例如下:GET_cat/nodesv返回结果示例如下:ipheap.percentram.percentcpuload_1mload_5mload_15mnode.rolemastername172.16.16.188529952.591.701.45mdi-elastic3172.16.16.187329950.990.991.19mdi-elastic2172.16.16.231699940.871.001.03mdi-elastic4172

  9. LinuxGUI自动化测试框架搭建(二十二)-框架主入口main.py设计&log日志调用 - 2

    (二十二)-框架主入口main.py设计&log日志调用和生成1测试目的2测试需求3需求分析4详细设计4.1新建存放日志目录log4.1.1配置config.py中写入log的目录4.2`baseInfo.py`中加入日志4.3`test_gedit.py`中加入日志4.4主函数入口main.py中调用日志5调用日志主函数main.py源码6`baseInfo.py`源码7`test_gedit.py`源码8运行效果9目前框架结构1测试目的组织运行所有的测试用例,并调用日志模块,便于问题定位。

  10. 基于ActiveMQ搭建MQTT服务备忘(二):webapp集成 - 2

    (1)为什么写这个话题(Why)读万卷书不如行千里路。这次搭建MQTT服务,遇到了一些误解,特此记录备忘。主要包括:(1)服务(Broker)的账户管理与网页管理平台的账户(2)与web应用的集成(Spring系)(2)ActiveMQ版本选择因为JAVA环境是JDK8,所以按兼容性考虑选择了ActiveMQ5.15的最后版本5.15.15。如果你是JDK11则可考虑ActiveMQ的最新版本5.17或5.18。ActiveMQ支持MQTTv3.1.1andv3.1。(3)ActiveMQ与web应用的集成主要介绍与Spring系的webapp集成(SpringBoot和SpringMVC)。

随机推荐