0.引言

公司开发需要用到redis,虽然有运维自动搭建,还是记录下如何搭建redis集群和Sentinel。

采用的是vagrant虚拟机+docker的方式进行搭建。

搭建思路:

  首先是借鉴下其他博客的docker搭建步骤,直接搭建。主要是:

https://blog.csdn.net/qq_40369435/article/details/91357479

  然后就是记录搭建过程中遇到的问题,以及如何一步步解决的。

  最后测试。

搭建的集群是:

  redis集群:1主2从

  sentinel集群:3台

1.基础安装

注:基础安装是根据已有博客搭建的,有很多问题,不是最终步骤。最终步骤在第三部分总结给出,当然也可能有问题,毕竟各个环境可能不同。

(1)在虚拟机中安装docker-compose

默认已经安装过了docker。

1)拉取安装包

curl -L "https://get.daocloud.io/docker/compose/releases/download/1.27.3/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose

2)给docker-compose增加执行权限

chmod +x /usr/local/bin/docker-compose

注:最开始安装docker-compose是先安装python的pip,再通过pip安装docker-compose,但升级pip时问题太多,干脆直接找个拉取源代码的直接下载。惭愧之前搞了那么久的python。

(2)搭建redis集群

1)新建docker-compose.yml文件

version: '2.0'
services:
master:
image: redis
container_name: redis-master
ports:
- 6379:6379 slave1:
image: redis
container_name: redis-slave-1
ports:
- 6380:6379
command: redis-server --slaveof redis-master 6379 slave2:
image: redis
container_name: redis-slave-2
ports:
- 6381:6379
command: redis-server --slaveof redis-master 6379

2)启动redis集群

docker-compose up -d

启动后,

docker ps;  # 查看容器启动情况

如果容器启动不成功,docker ps不会列出正在运行的容器,需要查看已经启动过的容器

docker ps -a;  #查看启动过的容器

这个时候,如果启动失败,通过docker ps -a知道启动失败的容器id,再通过查看日志的方式找出错误:

docker logs 容器id(一部分即可);  # 查看容器的日志
docker logs -f 容器id(一部分即可); # 动态查看容器的日志

(3)搭建sentinel集群

1)sentinel配置文件

一共三台sentinel,准备三份配置文件,分别是sentinel1.conf、sentinel2.conf和sentinel3.conf,将这三份配置文件放在

/usr/local/etc/redis/sentinel.conf目录下。

port 26379
dir "/tmp"
# 自定义集群名,其中 127.0.0.1 为 redis-master 的 ip,6379 为 redis-master 的端口,2 为最小投票数(因为有 3 台 Sentinel 所以可以设置成 2)
sentinel deny-scripts-reconfig yes
#自己的虚拟机ip地址
sentinel monitor mymaster 192.168.165.10 6379 2
sentinel config-epoch mymaster 0
sentinel leader-epoch mymaster 0
# Generated by CONFIG REWRITE(后面这3个注释掉了)
# sentinel known-replica mymaster 172.26.0.2 6379
# sentinel known-replica mymaster 172.26.0.3 6379
# sentinel current-epoch 0

同样的内容,复制到sentinel2.conf和sentinel3.conf'

2)docker-compose.yml

version: '2.0'
services:
sentinel1:
image: redis
container_name: redis-sentinel-1
ports:
- 26379:26379
command: redis-sentinel /usr/local/etc/redis/sentinel.conf
volumes:
- ./sentinel1.conf:/usr/local/etc/redis/sentinel.conf sentinel2:
image: redis
container_name: redis-sentinel-2
ports:
- 26380:26379
command: redis-sentinel /usr/local/etc/redis/sentinel.conf
volumes:
- ./sentinel2.conf:/usr/local/etc/redis/sentinel.conf sentinel3:
image: redis
container_name: redis-sentinel-3
ports:
- 26381:26379
command: redis-sentinel /usr/local/etc/redis/sentinel.conf
volumes:
- ./sentinel3.conf:/usr/local/etc/redis/sentinel.conf

docker-compose.yml文件也放在/usr/local/etc/redis/sentinel.conf目录下

3)启动sentinel集群

docker-compose up -d

redis集群和sentinel集群按照上面步骤,可以通过docker运行,以为已经搭建成功,也可以连接到redis集群中。测试在主库中写,两个从库中都可以读出来,从库也不可以写内容。但是测试主库下线时,此时2个从库并没有有一个切换到主库。开始进行找错。

2.找问题与解决

主要问题:

  redis集群的主从是成功的,但故障迁移时是失败的。

先看看测试故障迁移的方法:

  1)进入redis-master容器

docker exec -it redis-master /bin/bash

  2)进入redis环境

redis-cli -p 6379

  3)查看redis角色

info

查看,知道redis-master是master节点。同样步骤查看redis-slave-1和redis-slave-2,都是slave节点

  4)停掉master节点

docker stop redis-master

再去查看redis-slave-1和redis-slave-2,发现这两个节点还是slave,并没有一个成为master,表示sentinel故障转移失败。

注:之前没有找到查看sentinel日志的方法(docker logs -f 容器id),在master节点下线时直接查看sentinel的日志可以直观看到redis的下线、选举和当选主节点的过程。

初步认为原因可能是sentinel监控节点失败的原因:

查看过程:

  1)进入到redis-sentinel-1节点,查看节点信息

docker exec -it redis-sentinel-1/bin/bash
redis-cli -p 26379
sentinel master mymaster
sentinel slaves mymaster

  2)发现redis-slave节点都下线了

但实际redis-slave节点是在线的,表明是sentinel认为redis-slave下线 了。可能是之间网络不通的原因导致的。

此时,查找其他网页,发现可以看到sentinel的logs。

查看sentinel的日志:

docker logs redis-sentinel-1

有:

看日志,确实在sentinel启动后,redis-slave是下线了。

尝试1:

最开始看到WARN的信息:Device or resource busy,以为是设备被占用(conf文件会被sentinel再写入),就往这个方向解决:

出现这个Warning,原因可能是:不能修改配置文件,容器中的配置文件是挂载到外部的。(一般修改文件都是新生成一个然后替换原来的),就会报Device or resource busy.----->不是主要原因(因为发现其他可以正常故障迁移的也会有这个warning信息)

尝试2:
万能的防火墙、端口原因

检查本地的防火墙,发现防火墙是关闭的,不是我这边下线的原因。

尝试3:

sentinel.conf配置文件问题,没有开启参数

https://blog.csdn.net/weixin_30649859/article/details/97698005

按照上面思路解决,仍然行不通

尝试4:

找到关键性原因:sentinel和slave不能通信,导致sentinel认为slave下线了---》主动下线

https://blog.csdn.net/woluoyifan/article/details/84252705

https://www.cnblogs.com/erbiao/archive/2018/06/08/9156215.html

上面特别强调docker的1:1端口映射。但没有给出具体的解决方案。

继续找寻解决方法:

https://cloud.tencent.com/developer/article/1343834

https://www.cnblogs.com/JulianHuang/p/12650721.html

这篇文章具有决定性帮助作用,首先他考虑到了docker环境下端口映射问题,其次他考虑到了网络问题。

按照这篇文章从新搭建下,发现最后还是出现了redis-slave在sentinel一启动就下线的问题。

看评论,应该是配置文件中sentinel端口都一样,实际应该每个配置文件都不同的。按照这种方法进行修改,不幸的是,还是失败。

继续再这篇博客的思路上思考,里面提出了network和redis_defalut的网络配置,将重心放到解决这个上面。

最开始在配置文件中配置这个,启动redis-sentinel集群会报错:

按照上面的提示,进行docker network create redis_default操作,应该是创建这个网络,就可以成功启动sentinel集群。

按照道理说,redis-master中应该有自己的network信息的,可能是这篇博主的network信息是redis_default和我机器上的不同,不然怎么会又要创建一个。按照这个思路,进入到redis-master容器中,查看信息。

docker inspect redis-master

发现:

确实,我的机器上加redisconf_default

到这算是有个突破口了。

根据这几轮的探索,主要针对最后一篇博客做了如下几个点的修改:
1)redis集群的端口对应是:

6379:6379
6380:6379
6381:6379

这样在commond中 master的端口才是6379,在sentinel.conf中的端口也是6379。

2)sentinel文件夹的docker-compose.yml

networks:
default:
external:
name: redisconf_default

3)sentinel.conf

sentinel1.conf、sentinel2.conf和sentinel3.conf的port都不相同,分别是26379、26380和26381 。

sentinel monitor的ip地址是master节点的dockerip地址,port就是master的port。

经过上面的修改,发现故障迁移是成功的。

3.最终安装步骤

下面是适合我的机器的最终安装步骤,经过测试可以行的通。但不能保证完全没有问题。有问题就解决呗。

(1)安装docker-compose

curl -L "https://get.daocloud.io/docker/compose/releases/download/1.27.3/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose

(2)搭建redis集群

1)在/usr/local/etc/redis/redis.conf目录下,新建docker-compose.yml

version: '3'
services:
master:
image: redis
container_name: redis-master
command: redis-server --requirepass redis_pwd --masterauth redis_pwd
ports:
- 6379:6379
slave1:
image: redis
container_name: redis-slave-1
ports:
- 6380:6380
command: redis-server --slaveof redis-master 6379 --requirepass redis_pwd --masterauth redis_pwd
slave2:
image: redis
container_name: redis-slave-2
ports:
- 6381:6381
command: redis-server --slaveof redis-master 6379 --requirepass redis_pwd --masterauth redis_pwd

--requirepass:指定redis登陆的密码。redis集群指定了,sentinel也指定相同的,否则都不指定(没验证过)

2)docker-compose up -d启动redis集群

3)查看redis-master节点的docker-ip和network name

docker inspect redis-master

关键的是上面的redisconf_default和IPAddress

(2)搭建sentinel集群

1)在/usr/local/etc/redis/sentinel.conf目录下,新建docker-compose.yml

具体内容为:

version: '3'
services:
sentinel1:
image: redis
container_name: redis-sentinel-1
ports:
- 26379:26379
command: redis-sentinel /usr/local/etc/redis/sentinel.conf
volumes:
- ./sentinel1.conf:/usr/local/etc/redis/sentinel.conf
sentinel2:
image: redis
container_name: redis-sentinel-2
ports:
- 26380:26380
command: redis-sentinel /usr/local/etc/redis/sentinel.conf
volumes:
- ./sentinel2.conf:/usr/local/etc/redis/sentinel.conf
sentinel3:
image: redis
container_name: redis-sentinel-3
ports:
- 26381:26381
command: redis-sentinel /usr/local/etc/redis/sentinel.conf
volumes:
- ./sentinel3.conf:/usr/local/etc/redis/sentinel.conf
networks:
default:
external:
name: redisconf_default

2)在/usr/local/etc/redis/sentinel.conf目录下,新建sentinel1.conf、sentinel2.conf和sentinel3.conf

sentinel1.conf

port 26379
dir /tmp
sentinel monitor mymaster 172.20.0.3 6379 2
sentinel auth-pass mymaster redis_pwd
sentinel down-after-milliseconds mymaster 30000
sentinel parallel-syncs mymaster 1
sentinel failover-timeout mymaster 180000
sentinel deny-scripts-reconfig yes

sentinel2.conf的port为26380,sentinel3.conf的port为26381,其他都一样

3)docker-compose up -d启动sentinel集群

4.测试

sentinel启动之后,通过docker logs -f sentinel容器id看日志:

之前mymaster的192.168网段(错误的配置下)变成和现在slave的同网段了,就可以ping通了,后面没有+sdown slave的信息。就会一直阻塞在这,等待新的操作记录日志。

此时在另一个窗口关闭master节点:docker stop redis-master

日志为:

进入到sentinel的redis-cli中,sentinel slaves mymaster查看,slave都启动的

至此,搭建集群应该成功,有问题再记录解决。

docker搭建redis集群和Sentinel,实现故障转移的更多相关文章

  1. docker搭建redis集群

    一.简介 docker作为一个容器技术,在搭建资源隔离性服务上具有很大的优势,在一台服务器上可以启动多个docker容器,感觉每个在容器里面部署的服务就像是部署在不同的服务器上.此次基于docker以 ...

  2. 利用Docker搭建Redis集群

    Redis集群搭建 运行Redis镜像 分别使用以下命令启动3个Redis docker run --name redis-6379 -p 6379:6379 -d hub.c.163.com/lib ...

  3. Docker:Docker搭建Redis集群(6)

    国外的公有云实在是太慢了,经常time out 这里搜集几个国内出名的: hub.c.163.com (网易:https://c.163.com/hub#/m/home/) dev.aliyun.co ...

  4. 5分钟实现用docker搭建Redis集群模式和哨兵模式

    如果让你为开发.测试环境分别搭一套哨兵和集群模式的redis,你最快需要多久,或许你需要一天?2小时?事实是可以更短. 是的,你已经猜到了,用docker部署,真的只需要十几分钟. 一.准备工作 拉取 ...

  5. 使用docker搭建redis集群

    创建网卡 docker network create redis --subnet 172.20.0.0/ --gateway 172.20.0.1 通过脚本创建6个redis配置 for i in ...

  6. docker 搭建 redis 集群(哨兵模式)

    文件结构 1. redis-sentinel 1-1. docker-compose.yml 1-2. sentinel 1-2-1 docker-compose.yml 1-2-2 sentinel ...

  7. 基于Docker的redis集群搭建

    Redis集群官方介绍:http://www.redis.cn/topics/cluster-tutorial.html 基于Docker搭建Redis集群 环境:6个节点,三主三从 制作Redis镜 ...

  8. docker 实现redis集群搭建

    摘要:接触docker以来,似乎养成了一种习惯,安装什么应用软件都想往docker方向做,今天就想来尝试下使用docker搭建redis集群. 首先,我们需要理论知识:Redis Cluster是Re ...

  9. 从零开始学习docker之在docker中搭建redis(集群)

    docker搭建redis集群 docker-compose是以多容器的方式启动,非常适合用来启动集群 一.环境准备 云环境:CentOS 7.6 64位 二.安装docker-compose #需要 ...

随机推荐

  1. Atcoder ABC161 A~E

    传送门 A - ABC Swap 1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 ...

  2. C语言之库函数的模拟与使用

    C语言之库函数的模拟与使用 在我们学习C语言的过程中,难免会遇到这样的一种情况: 我们通常实现一个功能的时候,费尽心血的写出来,却有着满满的错,这时却有人来告诉你说:这个功能可以用相应的库函数来实现. ...

  3. Kubernets二进制安装(6)之部署主控节点服务--etcd

    Etcd是Kubernetes集群中的一个十分重要的组件,用于保存集群所有的网络配置和对象的状态信息. 整个kubernetes系统中一共有两个服务需要用到etcd用来协同和存储配置,分别是 网络插件 ...

  4. GUI编程

    组件 窗口 弹窗 面板 文本框 列表框 按钮 图片 监听事件 鼠标 键盘事 破解工具 简介 GUI的核心技术:Swing AWT 界面不美观 需要jre环境 为了了解MVC架构 了解监听. AWT 包 ...

  5. CNN可视化技术总结(四)--可视化工具与项目

    CNN可视化技术总结(一)-特征图可视化 CNN可视化技术总结(二)--卷积核可视化 CNN可视化技术总结(三)--类可视化 导言: 前面介绍了可视化的三种方法--特征图可视化,卷积核可视化,类可视化 ...

  6. Apple & 人体工程学

    Apple & 人体工程学 https://support.apple.com/zh-cn/HT205655 MBP 2018 https://help.apple.com/macbookpr ...

  7. Android APP 多端适配

    Android APP 多端适配 传统的多终端适配方案,是为大尺寸 Pad开发一个特定的 HD版本. 但是目前支持 Android 系统的设备类型越来越丰富,不同类型的设备尺寸也越来越多样化,特定的H ...

  8. codepen iframe theme id

    codepen iframe theme id iframe css theme demos See the Pen css margin collapsing (1. 相邻兄弟元素) by xgqf ...

  9. How to implement an accurate countdown timer with js

    How to implement an accurate countdown timer with js 如何用 js 实现一个精确的倒计时器 原理剖析 web worker js custom ti ...

  10. js & replaceAll & non-global RegExp bug

    js & replaceAll https://caniuse.com/#search=replaceAll https://developer.mozilla.org/en-US/docs/ ...