zoukankan      html  css  js  c++  java
  • docker搭建redis集群和Sentinel,实现故障转移

    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集群的端口对应是:

    63796379
    63806379
    63816379

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

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

    networks:
      default:
        external:
          name: redisconf_default

    3)sentinel.conf

    sentinel1.confsentinel2.confsentinel3.confport都不相同,分别是263792638026381 。

    sentinel monitorip地址是master节点的dockerip地址,port就是masterport

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

    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都启动的

     

     

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

  • 相关阅读:
    记一次动态依赖包版本过高解决过程
    Centos8更改国内源阿里云
    记一次vs2019安装GDB实现Cmake远程linux调试
    Tu te prends pour qui?
    中国高等教育是个啥:官僚主义的垄断黑洞
    关闭ThinkPad HDD APS Logging Service
    python Tlinter按钮接收多个参数
    第一章
    IE7的一个边界BUG
    让LumaQQ.NET支持接收群自定义表情和贴图
  • 原文地址:https://www.cnblogs.com/yq055783/p/14496449.html
Copyright © 2011-2022 走看看