Docker-compose搭建redis一主双从三哨兵

Docker-compose搭建redis一主双从三哨兵

  • 概述
    • 架构图
    • 服务器环境
    • docker编排文件
      • master
      • slave
    • redis主从配置
    • 启动主从容器
      • 验证redis主从
    • 哨兵
    • 启动哨兵
    • 验证failover(故障转移)
    • 填坑
    • springboot连接redis哨兵集群
      • pom添加依赖
      • yml配置连接信息

概述

Redis哨兵为Redis提供了高可用性。实际上这意味着你可以使用哨兵模式创建一个可以不用人为干预而应对各种故障的Redis部署。

哨兵模式还提供了其他的附加功能,如监控,通知,为客户端提供配置。

下面是在宏观层面上哨兵模式的功能列表:

  1. 监控:哨兵不断的检查master和slave是否正常的运行。
  2. 通知:当监控的某台Redis实例发生问题时,可以通过API通知系统管理员和其他的应用程序。
  3. 自动故障转移:如果一个master不正常运行了,哨兵可以启动一个故障转移进程,将一个slave升级成为master,其他的slave被重新配置使用新的master,并且应用程序使用Redis服务端通知的新地址。
  4. 配置提供者:哨兵作为Redis客户端发现的权威来源:客户端连接到哨兵请求当前可靠的master的地址。如果发生故障,哨兵将报告新地址。

架构图

Docker-compose搭建redis一主双从三哨兵_第1张图片

服务器环境

准备三台主机:172.20.10.27,172.20.10.28,172.20.10.29,分别安装Docker及docker-compose。
centos安装docker及docker-compose.

docker编排文件

分别在三台主机的/usr/local/redis目录下创建docker-compose.yml,内容如下:

master

version: "3"
services:
  redis-master:
    image: redis
    container_name: redis-master
    restart: always
    privileged: true
    environment:
      - TZ=Asia/Shanghai
    ports:
      - "6379:6379"
    volumes:
      - /usr/local/redis/data:/data
      - /usr/local/redis/conf/redis-master.conf:/usr/local/etc/redis/redis.conf
    command: redis-server /usr/local/etc/redis/redis.conf
  redis-sentinel:
    image: redis
    container_name: redis-sentinel
    restart: always
    privileged: true
    environment:
      - TZ=Asia/Shanghai
    ports:
      - "26379:26379"
    volumes:
      - /usrl/local/redis/conf/redis-sentinel.conf:/usr/local/etc/redis/sentinel.conf
    command: redis-sentinel /usr/local/etc/redis/sentinel.conf

slave

两个从节点的编排文件内容一致

version: "3"
services:
  redis-slave:
    image: redis
    container_name: redis-slave
    restart: always
    privileged: true
    environment:
      - TZ=Asia/Shanghai
    ports:
      - "6379:6379"
    volumes:
      - /usr/local/redis/data:/data
      - /usr/local/redis/conf/redis-slave.conf:/usr/local/etc/redis/redis.conf
    command: redis-server /usr/local/etc/redis/redis.conf
  redis-sentinel:
    image: redis
    container_name: redis-sentinel
    restart: always
    privileged: true
    environment:
      - TZ=Asia/Shanghai
    ports:
      - "26379:26379"
    volumes:
      - /usr/local/redis/conf/redis-sentinel.conf:/usr/local/etc/redis/sentinel.conf
    command: redis-sentinel /usr/local/etc/redis/sentinel.conf

redis主从配置

整个主从服务的所有节点使用统一的密码进行授权
master节点服务器/usr/local/redis/conf/redis-master.conf创建挂载的配置文件:

bind 0.0.0.0
protected-mode no
port 6379
#主节点也需要设置主节点的授权密码,因为角色会发生转变
masterauth 123456
requirepass 123456

slave节点配置,在两个从服务器/usr/local/redis/conf/redis-slave.conf创建挂载的配置文件:

bind 0.0.0.0
protected-mode no
port 6379
slaveof 172.20.10.27 6379
#主节点也需要设置主节点的授权密码,因为角色会发生转变
masterauth 123456
requirepass 123456
#因为使用docker部署的redis服务默认上报的元数据信息是docker容器内部ip与port,这里显示声明物理机的ip与port
slave-announce-ip 172.20.10.28
slave-announce-port 6379

启动主从容器

分别在三台服务器/usr/local/redis目录下执行docker-compose up -d命令创建启动容器。第一次执行该命令时docker-compsoe会根据yml文件中配置的image信息自动下载镜像。
在这里插入图片描述
可以看到名称为redis-master的容器状态为up,宿主机6379端口映射到容器内部6379端口,两台从主机信息雷同。

验证redis主从

主服务器执行,进入到容器内部

[root@localhost ~]# docker exec -it redis-master bash
#在容器里启动一个redis客户端,并授权
root@4a7fb46b57d3:/data# redis-cli
127.0.0.1:6379> auth 123456
#查看服务信息
127.0.0.1:6379> info
#主要查看一下信息
# Replication
role:master
connected_slaves:2
slave0:ip=172.20.10.28,port=6379,state=online,offset=5105669955,lag=0
slave1:ip=172.20.10.29,port=6379,state=online,offset=5105669998,lag=0

#ps对于从主机还要查看master_link_status这个属性值。slave上这个属性值为up就说明主从复制是OK的,否则就有问题。如果从机状态不为up,首先排查主机的端口是否被限,然后查看redis日志排查原因
role:slave
master_link_status:up

#主机点写入一个数据
127.0.0.1:6379> set test 123
OK
127.0.0.1:6379> get test
"123"
#退出redis客户端连接
127.0.0.1:6379> exit
#退出docker容器
root@4a7fb46b57d3:/data# exit

#登录到从节点去查看数据是否复制成功
127.0.0.1:6379> get test
"123"

哨兵

有了主从,那我们需要对其进行监控,Sentinel会不断地检查你的主服务器和从服务器是否运作正常。某个节点故障后,Sentinel 会开始一次自动故障迁移操作, 它会将失效主服务器的其中一个从服务器升级为新的主服务器, 并让失效主服务器的其他从服务器改为复制新的主服务器; 当客户端试图连接失效的主服务器时, 集群也会向客户端返回新主服务器的地址, 使得集群可以使用新主服务器代替失效服务器。Redis Sentinel 是一个分布式系统, 你可以在一个架构中运行多个 Sentinel 进程(Progress), 这些进程使用流言协议(Gossip Protocols)来接收关于主服务器是否下线的信息, 并使用投票协议(Agreement Protocols)来决定是否执行自动故障迁移, 以及选择哪个从服务器作为新的主服务器。虽然 Redis Sentinel 释出为一个单独的可执行文件 redis-sentinel , 但实际上它只是一个运行在特殊模式下的 Redis 服务器。
三个节点/usr/local/redis/conf/redis-sentinel.conf创建哨兵服务挂载的配置文件:

port 26379

daemonize no

pidfile "/var/run/redis-sentinel.pid"

logfile ""

sentinel myid 79c1f8276a8fedd78a9f987da8c85fce0ea7f751
sentinel deny-scripts-reconfig yes

dir "/tmp"

# 这里配置监控主服务的IP 端口 , 2表示两台机器判定主被动下线后,就进行failover(故障转移),这里需要遵循过半机制
sentinel monitor mymaster 172.20.10.27 6379 2

sentinel auth-pass mymaster 123456

sentinel config-epoch mymaster 3

sentinel leader-epoch mymaster 3

#同样需要声明物理机的ip与port
sentinel announce-ip "172.20.10.28"
sentinel announce-port 26379

启动哨兵

因为之前创建的docker-compose.yml文件中已经配置了哨兵的容器信息,所以直接启动就可以了。

#停止并删除之前创建的容器
docker-compose down
#创建并启动容器
docker-compose up -d 

在这里插入图片描述
查看docker sentinel日志
执行

docker logs redis-sentinel
 +monitor master mymaster 172.20.10.27 6379 quorum 2
 +slave slave 172.20.20.28:6379 172.20.20.28 6379 @ mymaster 172.20.10.27 6379
 +slave slave 172.20.20.29:6379 172.20.20.29 6379 @ mymaster 172.20.10.27 6379
 可以看到sentinel已经监控到了一主双从的信息。

或者进如sentinel容器内部,连接客户端来查看信息:

root@52adc847e9c6:/data# redis-cli -p 26379
127.0.0.1:26379> info
# Sentinel
sentinel_masters:1
sentinel_tilt:0
sentinel_running_scripts:0
sentinel_scripts_queue_length:0
sentinel_simulate_failure_flags:0
master0:name=mymaster,status=ok,address=172.20.10.27:6379,slaves=2,sentinels=3

验证failover(故障转移)

停止运行主服务器的上redis-master容器,然后查看redis-sentinel容器的日志追加了如下信息。
+odown master mymaster 172.20.10.27 6379 #quorum 3/2:表示名为mymaster主从中172.20.10.27这个主节点被哨兵监控到客观宕机。
+switch-master mymaster 172.20.10.27 6379 172.20.10.28 6379:表示配置变更,主服务器的 IP 和地址已由172.20.10.27 6379变更为172.20.10.28 6379

 [root@localhost ~]# docker stop redis-master 
 redis-master
 [root@localhost ~]# docker logs redis-sentinel
 1:X 01 Jun 2020 17:31:50.435 # +sdown master mymaster 172.20.10.27 6379
 1:X 01 Jun 2020 17:31:50.458 # +new-epoch 4
 1:X 01 Jun 2020 17:31:50.460 # +vote-for-leader 79c1f8276a8fedd78a9f987da8c85fce0ea7f751 4
 1:X 01 Jun 2020 17:31:50.527 # +odown master mymaster 172.20.10.27 6379 #quorum 3/2
 1:X 01 Jun 2020 17:31:50.527 # Next failover delay: I will not start a failover before  Mon Jun  1 17:37:50 2020
 1:X 01 Jun 2020 17:31:51.708 # +config-update-from sentinel 79c1f8276a8fedd78a9f987da8c85fce0ea7f751 172.20.10.28 26379 @ mymaster 172.20.10.27 6379
 1:X 01 Jun 2020 17:31:51.708 # +switch-master mymaster 172.20.10.27 6379 172.20.10.28 6379
 1:X 01 Jun 2020 17:31:51.708 * +slave slave 172.20.10.29:6379 172.20.10.29 6379 @   mymaster 172.20.10.28 6379
 1:X 01 Jun 2020 17:31:51.708 * +slave slave 172.20.10.27:6379 172.20.10.27 6379 @ mymaster 172.20.10.28 6379

进入容器中验证28节点的角色已经转变为master,且连接了一个从节点29。因为此时27节点还未恢复。

[root@localhost ~]# docker exec -it redis-slave bash
root@19259dab997c:/data# redis-cli
127.0.0.1:6379> auth 123456
OK
127.0.0.1:6379> info
# Replication
role:master
connected_slaves:1
slave0:ip=172.20.10.29,port=6379,state=online,offset=6198208362,lag=0

重启27节点上的redis-master容器中redis的信息,证明redis-master状态从down转变为up时,角色为slave,主节点信息为28。

[root@localhost ~]# docker start redis-master 
redis-master
[root@localhost ~]# docker exec -it redis-master bash
root@4a7fb46b57d3:/data# redis-cli 
127.0.0.1:6379> auth 123456
127.0.0.1:6379> info
# Replication
role:slave
master_host:172.20.10.28
master_port:6379
master_link_status:up

填坑

  • 因为使用docker来部署redis,所以slave和sentinel上报的元数据信息是docker容器内部ip与port,服务之间无法正常访问,所以:从节点需要配置宿主机的ip和端口:slave-announce-ip 172.20.10.28,slave-announce-port 6379。每个sentinel节点需要配置:sentinel announce-ip “172.20.10.28”
    sentinel announce-port 26379。
  • 使用docker挂载配置文件时需要注意配置文件的版本与redis镜像版本一致,否则会导致容器启动失败。

springboot连接redis哨兵集群

pom添加依赖

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

yml配置连接信息

spring:
  redis:
    sentinel:
      master: mymaster
      nodes: 172.20.10.27:26379,172.20.10.28:26379,172.20.10.29:26379
    password: 123456
	timeout: 6000ms
	database: 0

你可能感兴趣的:(docker,redis)