Docker-compose部署Redis主从哨兵
# Docker-compose部署Redis主从哨兵
# 1. 主从复制概述
主从复制,是指将一台Redis服务器的数据,复制到其他的Redis服务器。前者称为主节点(master),后者称为从节点(slave);数据的复制是单向的,只能由主节点到从节点。
默认情况下,每台Redis服务器都是主节点;且一个主节点可以有多个从节点(或没有从节点),但一个从节点只能有一个主节点。
主从复制的作用
主从复制的作用主要包括:
- 数据冗余:主从复制实现了数据的热备份,是持久化之外的一种数据冗余方式。
- 故障恢复:当主节点出现问题时,可以由从节点提供服务,实现快速的故障恢复;实际上是一种服务的冗余。
- 负载均衡:在主从复制的基础上,配合读写分离,可以由主节点提供写服务,由从节点提供读服务(即写Redis数据时应用连接主节点,读Redis数据时应用连接从节点),分担服务器负载;尤其是在写少读多的场景下,通过多个从节点分担读负载,可以大大提高Redis服务器的并发量。
- 高可用基石:除了上述作用以外,主从复制还是哨兵和集群能够实施的基础,因此说主从复制是Redis高可用的基础
# 2. 实验环境
[root@control01 ~]# docker version
Client: Docker Engine - Community
Version: 20.10.12
API version: 1.41
Go version: go1.16.12
Git commit: e91ed57
Built: Mon Dec 13 11:45:41 2021
OS/Arch: linux/amd64
Context: default
Experimental: true
Server: Docker Engine - Community
Engine:
Version: 20.10.12
API version: 1.41 (minimum version 1.12)
Go version: go1.16.12
Git commit: 459d0df
Built: Mon Dec 13 11:44:05 2021
OS/Arch: linux/amd64
Experimental: false
containerd:
Version: 1.4.12
GitCommit: 7b11cfaabd73bb80907dd23182b9347b4245eb5d
runc:
Version: 1.0.2
GitCommit: v1.0.2-0-g52b36a2
docker-init:
Version: 0.19.0
GitCommit: de40ad0
# 3. 架构
典型的哨兵架构图如下所示:
它由两部分组成,哨兵节点和数据节点:
- 哨兵节点:哨兵系统由一个或多个哨兵节点组成,哨兵节点是特殊的redis节点,不存储数据。
- 数据节点:主节点和从节点都是数据节点。
# 4. 部署主从
目的:1个主节点、2个从节点和3个哨兵节点
⚫创建一个家目录用于存放Redis集群的compose的文件。
⚫注意,如果设置了Redis客户端访问密码requirepass, 那么也要设置相同的副本集同步密码masterauth。
⚫另外我们后面使用哨兵模式能够完成故障转移,现有的Master可能会变成Slave,故在当前Master容器中也要携带masterauth参数。
⚫执行docker-compose up -d会产生3个Redis容器,分别映射到宿主机6380、6381、6382端口, 默认连接在go-default网桥。
[root@control01 ~]# mkdir -p /home/Docker/docker-compose/redis && cd /home/Docker/docker-compose/redis
[root@control01 redis]# cat docker-compose.yaml
version: '3'
services:
master:
image: redis
container_name: redis-master
command: redis-server --requirepass 123456 --masterauth 123456
ports:
- 6380:6379
slave1:
image: redis
container_name: redis-slave-1
ports:
- 6381:6379
command: redis-server --slaveof redis-master 6379 --requirepass 123456 --masterauth 123456
slave2:
image: redis
container_name: redis-slave-2
ports:
- 6382:6379
command: redis-server --slaveof redis-master 6379 --requirepass 123456 --masterauth 123456
运行并且查看当前的docker-compose进程。
[root@control01 redis]# docker-compose up -d
Creating network "redis_default" with the default driver
Creating redis-slave-2 ... done
Creating redis-slave-1 ... done
Creating redis-master ... done
[root@control01 redis]# docker-compose ps
Name Command State Ports
-------------------------------------------------------------------------------------------------
redis-master docker-entrypoint.sh redis ... Up 0.0.0.0:6380->6379/tcp,:::6380->6379/tcp
redis-slave-1 docker-entrypoint.sh redis ... Up 0.0.0.0:6381->6379/tcp,:::6381->6379/tcp
redis-slave-2 docker-entrypoint.sh redis ... Up 0.0.0.0:6382->6379/tcp,:::6382->6379/tcp
# 5.部署哨兵
⚫很明显我们即将搭建的Sentinel容器需要能访问到以上3个容器,故需要在形成Sentinel的Dokcer-compose 使用外置的redis-default
网桥。
⚫创建数据卷,将redis哨兵的需要的配置文件通过数据卷持久化挂载。
⚫查看当前docker网络,需要查看当前新增的redis主从是使用的那个网络。
[root@control01 sentinel]# docker network ls
NETWORK ID NAME DRIVER SCOPE
f5cf83b79660 bridge bridge local
dc1bc35819ac go_default bridge local #这里查看的是使用这个
7216b238150c host host local
d0504c7747a7 none null local
⚫编写docker-compose的yaml文件。
[root@control01 sentinel]# pwd
/home/Docker/docker-compose/redis/sentinel
[root@control01 sentinel]# cat docker-compose.yaml
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: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
networks:
default:
external:
name: go_default
⚫创建哨兵文件,将如下内容拷贝进去。
[root@control01 sentinel]# cat sentinel1.conf
port 26379
dir /tmp
sentinel monitor mymaster 172.26.0.4 6379 2
sentinel auth-pass mymaster 123456
sentinel down-after-milliseconds mymaster 30000
sentinel parallel-syncs mymaster 1
sentinel failover-timeout mymaster 180000
sentinel deny-scripts-reconfig yes
注意,以上 172.26.0.4是之前Redis Master/slave启动之后Master节点的IP,通过docker inspect [containerIP]获取, 这里我们要配合设置Master/Slave访问密码。
⚫复制两份sentinel1.conf文件,容器挂载需要.
[root@control01 sentinel]# cp sentinel1.conf sentinel2.conf
[root@control01 sentinel]# cp sentinel1.conf sentinel3.conf
⚫运行并且查看当前的进程。
[root@control01 sentinel]# docker-compose up -d
Creating redis-sentinel-2 ... done
Creating redis-sentinel-1 ... done
Creating redis-sentinel-3 ... done
[root@control01 sentinel]# docker-compose ps
Name Command State Ports
---------------------------------------------------------------------------------------------------------------
redis-sentinel-1 docker-entrypoint.sh redis ... Up 0.0.0.0:26379->26379/tcp,:::26379->26379/tcp,6379/tcp
redis-sentinel-2 docker-entrypoint.sh redis ... Up 0.0.0.0:26380->26379/tcp,:::26380->26379/tcp,6379/tcp
redis-sentinel-3 docker-entrypoint.sh redis ... Up 0.0.0.0:26381->26379/tcp,:::26381->26379/tcp,6379/tcp
# 6.验证
⚫进入redis-master容器查看主从关系。
[root@control01 redis]# docker exec -it redis-master /bin/bash
root@58af77dcfefa:/data# redis-cli -h localhost
localhost:6379> auth 123456
OK
localhost:6379> info replication
# Replication
role:master
connected_slaves:2
slave0:ip=172.27.0.2,port=6379,state=online,offset=826,lag=1
slave1:ip=172.27.0.4,port=6379,state=online,offset=826,lag=1
master_failover_state:no-failover
master_replid:337f0e6d5d9cd7bf50c7b8f08997ea9c5807642b
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:826
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:826