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. SPF POJ - 1523 割点+并查集

    题意: 问你这个图中哪个点是割点,如果把这个点去掉会有几个子网 代码: 1 //给你几个点,用着几个点形成了一个图.输入边形成的图,问你这个图中有多少个割点.每一个割点去掉后会形成几个强连通分量 2 ...

  2. WPF 之命令(七)

    一.前言 ​ 事件的作用是发布和传播一些消息,消息送达接收者,事件的使命也就完成了,至于消息响应者如何处理发送来的消息并不做规定,每个接收者可以使用自己的行为来响应事件.即事件不具有约束力. ​ 命令 ...

  3. 国产网络损伤仪SandStorm -- 如何连接设备

    国产网络损伤仪SandStorm可以模拟出带宽限制.时延.时延抖动.丢包.乱序.重复报文.误码.拥塞等网络状况,在实验室条件下准确可靠地测试出网络应用在真实网络环境中的性能,以帮助应用程序在上线部署前 ...

  4. next v5升级到next v7需要注意的地方

    title: next v5升级到next v7需要注意的地方 date: 2020-03-04 categories: web tags: [hexo,next] 大部分的设置都是一样的,但有一些细 ...

  5. P类问题,NP,NPC,HPHard,coNP,NPI问题 的简单认识

    参考<算法设计技巧与分析>--沙特 问题可以分为判定类问题和最优化问题,判定类问题可以转化为最优化问题,所以下面讨论的是判定类的问题. P类问题是可以在多项式时间  采用确定性算法给出解 ...

  6. 线程池原理讲解——ThreadPoolExecutor

    [这是前几天的存货,留着没发表,今天又复习一遍,润化了部分内容,继续干] 说线程池前,先简单回顾一下线程的状态吧: 1.线程状态转换 线程的五种状态,及其转换关系: 2.线程创建方式 三种:两个接口一 ...

  7. JavaScript中的对象引用和复制

    在JavaScript分为两种原始值和引用值类型,原始值之间的复制是值对值得复制,而引用类型则是引用对引用的复制: // 原始值的复制: let num1 = 1; let num2 = num1; ...

  8. Keras 报错: Error when checking target: expected dense_4...

    笔者此处是一个回归任务, 最后一层是: ... pred = Dense(1)(x) 在最后一个Dense层前加上x = Flatten()(x)即可.

  9. iPhone 12 导入通讯录排序 Bug

    iPhone 12 导入通讯录排序 Bug iOS iOS 通讯录排序问题 Huawei OK solution iOS 切换中英文,修复排序通讯录 bug Awesome iOS Contacts ...

  10. TypeScript Interface vs Types All In One

    TypeScript Interface vs Types All In One TypeScript https://www.typescriptlang.org/docs/handbook/adv ...