zoukankan      html  css  js  c++  java
  • Docker搭建redis集群

    Docker搭建redis集群

        在《Redis的三种集群模式这篇文章中,我们初步认识了redis三种不同的集群模式,接下来这篇文章,我们再通过实际部署搭建来对它们进行进一步的学习和了解。

        一、主从复制模式

        前提条件

        这里准备了三台虚拟主机:192.168.205.10、192.168.205.11、192.168.205.12

    •     三台主机均安装好centos7系统
    •     三台主机均安装好docker并启动docker(我这里安装的docker版本为20.10.7)
    •     三台主机拉取redis镜像(我这里使用redis6.2.2版本,并将镜像推送到了私有仓库)

         

        1、三台主机都要进行的操作

        1)创建存放redis.conf文件的目录

        mkdir -p  /root/hxq/redis

        2)拉取redis配置文件

        确定系统下是否安装wget命令,如果没有,则执行安装命令:yum -y install wget

        执行命令:

        cd /root/hxq/redis

        wget -c http://download.redis.io/redis-stable/redis.conf

        3)启动redis容器

        docker run --name redis -v /root/hxq/redis/redis.conf:/usr/local/etc/redis/redis.conf -d -p 6379:6379  192.168.205.10:5000/redis:6.2.2

        说明:

        -p 端口映射,6379是redis端口 

        192.168.205.10:5000/redis:6.2.2为镜像名称

        2、进入三台主机redis容器内部

        1)进入redis容器: docker exec -it 容器id/容器名称 /bin/bash

        2)进入redis客户端:redis-cli

        3)查询当前主机redis的信息

        执行命令:info replication

        

       我们发现三台都是主节点

       3、手动绑定主节点

       说明:这里以192.168.205.10为主节点,192.168.205.11和192.168.205.12为从节点

       1)分布进入11和12主机上的redis容器内部,进入redis客户端

       执行命令:redis-cli

       2)绑定主redis信息:SLAVEOF  主ip   主端口

      执行命令:SLAVEOF  192.168.205.10  6379

       3)info 查询节点信息

       

       我们再进入10服务器,查看节点信息:

       

       至此,redis主从已经搭建完毕

      4、测试主从复制

         1)测试读写数据

        主节点写入数据

         

         从节点同步数据

         

         从节点没有写入权限

         

        由此我们可以看出,主可以读写,从只能读。这也是redis集群的特点:读写分离。

        2)客户端连接

        建议用主节点连接就可以了,因为可以读写。用从节点只能读取数据。

        

        另外,我们可以进一步认识到主从复制的缺点:

        1)不具备自动容错与恢复功能,master或slave的宕机都可能导致客户端请求失败,需要等待机器重启或手动切换客户端IP才能恢复

        2)难以支持在线扩容,Redis的容量受限于单机配置

     

        二、哨兵模式(Sentinel)

        在redis主从复制基础上搭建redis哨兵模式

        1、配置文件

        有两种方式创建sentinel.conf:

        1)通过wget命令获取sentinel的配置文件

        wget http://download.redis.io/redis-stable/sentinel.conf

        然后再根据实际情况进行修改

        2)手动创建

        cd  /root/hxq/redis-sentinel

        vim sentinel.conf

     1 port 26379
     2 
     3 daemonize yes
     4 
     5 logfile "/var/log/redis/sentinel.log"
     6 
     7 # 监控名为redis-master集群;其主节点信息为【192.168.205.10:6379】;当发生意外时,至少有两个节点同意,这里的2为quorum,投票数
     8 
     9 sentinel monitor redis-master 192.168.205.10 6379 2
    10 
    11 # 监控认为超过5S还没响应,就认为redis-master集群挂了
    12 
    13 sentinel down-after-milliseconds redis-master 5000
    14 
    15 # 对sentinel集群暴露自己的ip和端口
    16 
    17 sentinel announce-ip 192.168.205.10
    18 
    19 sentinel announce-port 26379

       2、运行哨兵

       docker run -it --name sentinel -p 26379:26379 -v /root/hxq/redis-sentinel/sentinel.conf:/usr/local/etc/redis/sentinel.conf -d  redis镜像名称 bash

       1)进入容器

       docker exec -it sentinel  bash

       2)创建日志目录和文件

       mkdir /var/log/redis

       touch /var/log/redis/sentinel.log

       3)启动哨兵

       redis-sentinel  /usr/local/etc/redis/sentinel.conf

       4)查看日志:

         cat /var/log/redis/sentinel.log

         

         在另外两台机器上按照同样的方法在一个容器中运行sentinel,配置文件有所不同:

         # 对sentinel集群暴露自己的ip和端口

         sentinel announce-ip ip地址

         说明:这里的ip地址为sentinel所在服务器的ip地址,因为这里使用docker启动容器,如果不给定ip地址的话,就会默认使用docker分配的ip地址,就会出现问题

         3、进入sentinel客户端

         redis-cli -p 26379

         执行命令,查看哨兵节点的信息:info sentinel

          

          4、验证failover(故障转移)

          为了验证哨兵机制下的自动主从切换,我们将主服务器192.168.205.10上的redis容器先停掉

          执行命令:docker stop redis

            

          Sentinel包括两个重要的术语:主观下线客观下线

          主观下线(Subjectively Down, 简称 SDOWN)指的是单个 Sentinel 实例对服务器做出的下线判断。

          客观下线(Objectively Down, 简称 ODOWN)指的是多个 Sentinel 实例在对同一个服务器做出 SDOWN 判断, 并且通过SENTINEL is-master-down-by-addr 命令互相交流之后, 得出的服务器下线判断。

        5、sentinel服务日志说明

        Sentinel服务启动后会打印一些相关日志信息,以下是相关日志特殊字符说明:

     1 +reset-master :主服务器已被重置。
     2 
     3 +slave :一个新的从服务器已经被 Sentinel 识别并关联。
     4 
     5 +failover-state-reconf-slaves :故障转移状态切换到了reconf-slaves 状态。
     6 
     7 +failover-detected :另一个 Sentinel 开始了一次故障转移操作,或者一个从服务器转换成了主服务器。
     8 
     9 +slave-reconf-sent :领头(leader)的 Sentinel 向实例发送了 SLAVEOF 命令,为实例设置新的主服务器。
    10 
    11 +slave-reconf-inprog :实例正在将自己设置为指定主服务器的从服务器,但相应的同步过程仍未完成。
    12 
    13 +slave-reconf-done :从服务器已经成功完成对新主服务器的同步。
    14 
    15 -dup-sentinel :对给定主服务器进行监视的一个或多个 Sentinel 已经因为重复出现而被移除 —— 当 Sentinel 实例重启的时候,就会出现这种情况。
    16 
    17 +sentinel :一个监视给定主服务器的新 Sentinel 已经被识别并添加。
    18 
    19 +sdown :给定的实例现在处于主观下线状态。
    20 
    21 -sdown :给定的实例已经不再处于主观下线状态。
    22 
    23 +odown :给定的实例现在处于客观下线状态。
    24 
    25 -odown :给定的实例已经不再处于客观下线状态。
    26 
    27 +new-epoch :当前的纪元(epoch)已经被更新。
    28 
    29 +try-failover :一个新的故障迁移操作正在执行中,等待被大多数 Sentinel 选中(waiting to be elected by themajority)。
    30 
    31 +elected-leader :赢得指定纪元的选举,可以进行故障迁移操作了。
    32 
    33 +failover-state-select-slave :故障转移操作现在处于select-slave 状态 —— Sentinel 正在寻找可以升级为主服务器的从服务器。
    34 
    35 no-good-slave :Sentinel 操作未能找到适合进行升级的从服务器。Sentinel 会在一段时间之后再次尝试寻找合适的从服务器来进行升级,又或者直接放弃执行故障转移操作。
    36 
    37 selected-slave :Sentinel 顺利找到适合进行升级的从服务器。
    38 
    39 failover-state-send-slaveof-noone :Sentinel 正在将指定的从服务器升级为主服务器,等待升级功能完成。
    40 
    41 failover-end-for-timeout :故障转移因为超时而中止,不过最终所有从服务器都会开始复制新的主服务器(slaves will eventually be configured to replicate with the newmaster anyway)。
    42 
    43 failover-end :故障转移操作顺利完成。所有从服务器都开始复制新的主服务器了。
    44 
    45 +switch-master :配置变更,主服务器的 IP 和地址已经改变。 这是绝大多数外部用户都关心的信息。
    46 
    47 +tilt :进入 tilt 模式。
    48 
    49 -tilt :退出 tilt 模式。

       

         三、Redis Cluster集群

        单机部署

         1、创建网络

        1)为什么需要创建网络?

      因为默认的 bridge 网络是无法使用 DNS 的,所以我们就需要自定义网络。说简单点就是为了让容器可以直接通过容器名称进行通信。

        从 Docker 1.10 版本开始,docker daemon 实现了一个内嵌的 DNS server,使容器可以直接通过容器名称进行通信。方法很简单,只要在创建容器时使用 --name 为容器命名即可。

        但是使用 Docker DNS 有个限制:只能在 user-defined 网络中使用。也就是说,默认的 bridge 网络是无法使用 DNS 的,所以我们就需要自定义网络。通过 docker network create 命令可以创建自定义网络模式,默认为 bridge 网桥/桥接模式,完整命令如下:

        docker network create redis-net

        2)查看网络模式

        执行命令:docker network ls 

        

        3)查看网络的详细信息

        执行命令:docker network inspect redis-net

        

        2、编写Redis配置文件

        cd /root/hxq/redis-cluster

        vim  redis-cluster.tmpl

        redis-cluster.tmpl 文件内容如下:

     1 port ${PORT}
     2 
     3 requirepass 1234
     4 
     5 masterauth 1234
     6 
     7 protected-mode no
     8 
     9 daemonize no
    10 
    11 appendonly yes
    12 
    13 cluster-enabled yes
    14 
    15 cluster-config-file nodes.conf
    16 
    17 cluster-node-timeout 15000
    18 
    19 cluster-announce-ip 192.168.205.10
    20 
    21 cluster-announce-port ${PORT}
    22 
    23 cluster-announce-bus-port 1${PORT}

        1)相关配置参数说明

        2)每个Redis集群节点都需要打开两个TCP连接

        一个用于为客户端提供服务的正常 Redis TCP 端口,例如 6379。还有一个基于 6379 端口加 10000 的端口,比如 16379。

        第二个端口用于集群总线,这是一个使用二进制协议的节点到节点通信通道。节点使用集群总线进行故障检测、配置更新、故障转移授权等等。客户端永远不要尝试与集群总线端口通信,与正常的 Redis 命令端口通信即可,但是请确保防火墙中的这两个端口都已经打开,否则 Redis 集群节点将无法通信。

        在 redis-cluster 目录下执行以下命令:

        循环创建 8001 - 8006 相关的目录及文件

    1 for port in `seq 8001 8006`; do 
    2 
    3   mkdir -p ${port}/conf 
    4 
    5   && PORT=${port} envsubst < redis-cluster.tmpl > ${port}/conf/redis.conf 
    6 
    7   && mkdir -p ${port}/data;
    8 
    9 done

         查看命令执行结果,如果没有 tree 命令先安装 :yum install -y tree

         执行命令:tree /root/hxq/redis-cluster/

        

        查看每个节点的配置文件详细信息

        cat /root/hxq/redis-cluster/800{1..6}/conf/redis.conf

     1 port 8001
     2 requirepass 1234
     3 masterauth 1234
     4 protected-mode no
     5 daemonize no
     6 appendonly yes
     7 cluster-enabled yes
     8 cluster-config-file nodes.conf
     9 cluster-node-timeout 15000
    10 cluster-announce-ip 192.168.205.10
    11 cluster-announce-port 8001
    12 cluster-announce-bus-port 18001
    13 port 8002
    14 requirepass 1234
    15 masterauth 1234
    16 protected-mode no
    17 daemonize no
    18 appendonly yes
    19 cluster-enabled yes
    20 cluster-config-file nodes.conf
    21 cluster-node-timeout 15000
    22 cluster-announce-ip 192.168.205.10
    23 cluster-announce-port 8002
    24 cluster-announce-bus-port 18002
    25 port 8003
    26 requirepass 1234
    27 masterauth 1234
    28 protected-mode no
    29 daemonize no
    30 appendonly yes
    31 cluster-enabled yes
    32 cluster-config-file nodes.conf
    33 cluster-node-timeout 15000
    34 cluster-announce-ip 192.168.205.10
    35 cluster-announce-port 8003
    36 cluster-announce-bus-port 18003
    37 port 8004
    38 requirepass 1234
    39 masterauth 1234
    40 protected-mode no
    41 daemonize no
    42 appendonly yes
    43 cluster-enabled yes
    44 cluster-config-file nodes.conf
    45 cluster-node-timeout 15000
    46 cluster-announce-ip 192.168.205.10
    47 cluster-announce-port 8004
    48 cluster-announce-bus-port 18004
    49 port 8005
    50 requirepass 1234
    51 masterauth 1234
    52 protected-mode no
    53 daemonize no
    54 appendonly yes
    55 cluster-enabled yes
    56 cluster-config-file nodes.conf
    57 cluster-node-timeout 15000
    58 cluster-announce-ip 192.168.205.10
    59 cluster-announce-port 8005
    60 cluster-announce-bus-port 18005
    61 port 8006
    62 requirepass 1234
    63 masterauth 1234
    64 protected-mode no
    65 daemonize no
    66 appendonly yes
    67 cluster-enabled yes
    68 cluster-config-file nodes.conf
    69 cluster-node-timeout 15000
    70 cluster-announce-ip 192.168.205.10
    71 cluster-announce-port 8006
    72 cluster-announce-bus-port 18006

         3、创建redis容器

         1)创建容器

         将宿主机的 8001 ~ 8006 之间的端口与 6 个 Redis 容器映射,并将宿主机的目录与容器内的目录进行映射(目录挂载)。记得指定网络模式,使用我们自己创建的 redis-net 网络。

     1 for port in $(seq 8001 8006); do 
     2 
     3   docker run -di -p ${port}:${port} -p 1${port}:1${port} 
     4 
     5   --restart always --name redis-${port} --net redis-net 
     6 
     7   -v /root/hxq/redis-cluster/${port}/conf/redis.conf:/usr/local/etc/redis/redis.conf 
     8 
     9   -v /root/hxq/redis-cluster/${port}/data:/data 
    10 
    11   192.168.205.10:5000/redis:6.2.2  redis-server /usr/local/etc/redis/redis.conf; 
    12 
    13 done

         创建如下图:

         

         查看容器是否创建成功

         执行命令: docker ps -n 6

         

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

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

        

        4、创建 Redis Cluster集群

        1)进入容器

        docker exec -it redis-8001 bash

        2)切换至指定目录

        cd /usr/local/bin/

        3)执行命令,创建集群

        redis-cli -a 1234 --cluster create 172.19.0.2:8001 172.19.0.3:8002 172.19.0.4:8003 172.19.0.5:8004 172.19.0.6:8005 172.19.0.7:8006 --cluster-replicas 1

        说明:命令中的--cluster-replicas 代表主从节点的比例,这里因为是3主3从,所以参数为1

        创建过程,如下图:

         

        至此一个高可用的 Redis Cluster 集群搭建完成,如下图所示,该集群中包含 6 个 Redis 节点,3 主 3 从。三个主节点会分配槽,处理客户端的命令请求,而从节点可用在主节点故障后,顶替主节点。

        

         4)检查集群状态

        # 使用IP

        redis-cli -a  1234  --cluster  check 192.168.205.10:8001

        # 使用容器名称(推荐这种方式)

        redis-cli  -a  1234  --cluster  check redis-8001:8001

        

        5)查看集群信息和节点信息

        随便进入一个容器节点,然后    cd /usr/local/bin

        # 连接至集群某个节点

        redis-cli -c -a 1234 -h redis-8003 -p 8003

        # 查看集群信息

        cluster info

        #查看集群结点信息

        cluster nodes

        如下图:

         

        6)SET/GET操作

         

        说明:在 Redis Cluster 集群模式中,无论连接哪个节点,每次我们执行写入或者读取操作的时候,所有的键会根据哈希函数运算并映射到 0 ~ 16383 整数槽内,如果恰好对应的槽就在你当前连接的节点中,则直接执行命令,否则重定向至对应节点执行命令。

        7)计算键属于那个槽

        计算公式:slot = CRC16(key) & 16383

        执行命令: cluster keyslot  "name"

        5、客户端连接

     最后测试下客户端连接操作,随便哪个节点,看看可否通过外部访问 Redis Cluster 集群。

        

        

      

        至此使用多个容器搭建 Redis Cluster 集群环境就到这里。

         多机环境

        为了让环境更加真实,我们再用多机环境来部署一遍:

        192.168.10.11

        192.168.10.12

        整体搭建步骤还是分为4步:

    •     下载 Redis 镜像(其实这步可以省略,因为创建容器时,如果本地镜像不存在,就会去远程拉取)
    •     编写 Redis 配置文件
    •     创建 Redis 容器
    •     创建 Redis Cluster 集群

         由于在多机环境与单机环境下部署都很相似,为了让文章篇幅显得不那么冗余,这里只提出与单机部署上有区别的地方。

         1、网络

        按照 Redis 官网的提示,为了使 Docker 与 Redis Cluster 兼容,您需要使用 Docker 的 host 网络模式

        host 网络模式需要在创建容器时通过参数 --net host 或者 --network host 指定,host 网络模式可以让容器共享宿主机网络栈,容器将不会虚拟出自己的网卡,配置自己的 IP 等,而是使用宿主机的 IP 和端口。所以这里不需要自定义网络,在后面创建容器的时候,--net参数需指定为host

        2、配置文件

        cd /root/hxq/redis-cluster

        vi redis-cluster.tmpl

        11机器和12机器上面的配置有所不同:  

        192.168.205.11服务器上面的redis-cluster.tmpl:

    port ${PORT}
    requirepass 1234
    masterauth 1234
    protected-mode no
    daemonize no
    appendonly yes
    cluster-enabled yes
    cluster-config-file nodes.conf
    cluster-node-timeout 15000
    cluster-announce-ip 192.168.205.11
    cluster-announce-port ${PORT}
    cluster-announce-bus-port 1${PORT}

        192.168.205.12服务器上面的redis-cluster.tmpl:

     1 port ${PORT}
     2 requirepass 1234
     3 masterauth 1234
     4 protected-mode no
     5 daemonize no
     6 appendonly yes
     7 cluster-enabled yes
     8 cluster-config-file nodes.conf
     9 cluster-node-timeout 15000
    10 cluster-announce-ip 192.168.205.12
    11 cluster-announce-port ${PORT}
    12 cluster-announce-bus-port 1${PORT}

       3、创建配置文件和目录

       1)循环创建相关的目录及文件

        cd /root/hxq/redis-cluster

       11服务器:

    1 for port in `seq 8001 8003`; do 
    2 
    3   mkdir -p ${port}/conf 
    4 
    5   && PORT=${port} envsubst < redis-cluster.tmpl > ${port}/conf/redis.conf 
    6 
    7   && mkdir -p ${port}/data;
    8 
    9 done

        12服务器:

    1 for port in `seq 8004 8006`; do 
    2 
    3   mkdir -p ${port}/conf 
    4 
    5   && PORT=${port} envsubst < redis-cluster.tmpl > ${port}/conf/redis.conf 
    6 
    7   && mkdir -p ${port}/data;
    8 
    9 done

        2)查看配置文件 

        如果未安装tree命令,则执行:yum install -y tree

        tree  /root/hxq/redis-cluster

        11服务器:cat /root/hxq/redis-cluster/800{1..3}/conf/redis.conf

        12服务器:cat /root/hxq/redis-cluster/800{4..6}/conf/redis.conf

         4、创建Redis容器

        11服务器上面,创建容器:

     1 for port in $(seq 8001 8003); do 
     2 
     3   docker run -di --restart always --name redis-${port} --net host 
     4 
     5   -v /root/hxq/redis-cluster/${port}/conf/redis.conf:/usr/local/etc/redis/redis.conf 
     6 
     7   -v /root/hxq/redis-cluster/${port}/data:/data 
     8 
     9   192.168.205.10:5000/redis:6.2.2 redis-server /usr/local/etc/redis/redis.conf; 
    10 
    11 done

         12服务器上面,创建容器:

     1 for port in $(seq 8004 8006); do 
     2 
     3   docker run -di --restart always --name redis-${port} --net host 
     4 
     5   -v /root/hxq/redis-cluster/${port}/conf/redis.conf:/usr/local/etc/redis/redis.conf 
     6 
     7   -v /root/hxq/redis-cluster/${port}/data:/data 
     8 
     9   192.168.205.10:5000/redis:6.2.2  redis-server /usr/local/etc/redis/redis.conf; 
    10 
    11 done

        查看容器是否创建成功:docker ps -n 3 

       注意:这里创建容器时,指定--net为host

        5、创建 Redis Cluster 集群

       1)随便进入一个容器节点,并进入 /usr/local/bin/ 目录

        docker exec -it  redis-8001 bash

        cd  /usr/local/bin/

       2)创建集群

       redis-cli -a 1234 --cluster create 192.168.205.11:8001 192.168.205.11:8002 192.168.205.11:8003 192.168.205.12:8004 192.168.205.12:8005 192.168.205.12:8006 --cluster-replicas 1

       

       6、连接至集群某个节点

       redis-cli -c -a 1234 -h 192.168.205.11 -p 8001

       注意:因为使用host模式,这个地方-h参数 应该取宿主机ip地址

       

       至此一个高可用的 Redis Cluster 集群搭建完成。

     

     

       参考链接:

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

       https://juejin.cn/post/6844903908398071815

       https://juejin.cn/post/6868814738751488008

       https://cloud.tencent.com/developer/news/688466

  • 相关阅读:
    PHP 动态执行
    jenkins 'cordova' command not recognised on Jenkins Windows slave
    ionic3 实现扫码功能
    解决ionic3 android 运行出现Application Error
    解决添加codova plugin 编译出现问题:Execution failed for task ':processDebugManifest'.
    菜鸟的 Sass 学习笔记
    解决关于ios访问相机闪退问题
    解决ios关于:ERROR Internal navigation rejected
    Angular4 组件通讯方法大全
    ASP.NET MVC5 使用MiniProfiler 监控MVC性能
  • 原文地址:https://www.cnblogs.com/hld123/p/15140253.html
Copyright © 2011-2022 走看看