一 概述
哨兵模式是一主多从的模式,我这里使用的是一主二从的模式,当主节点发生故障下线之后,哨兵就会从新选举一个从节点来当主节点。
一. 准备
0> redis镜像准备
docker pull redis:4.0.14-buster
1> 目录准备
在linux系统下创建这样的目录:
/home/docker/redis/sentienl/redis
/home/docker/redis/sentienl/sentinel
2> 准备配置文件redis.conf
因为是一主二从,所以redis.conf要准备三份。
- 在/home/docker/redis/sentienl/redis/16379 下放:
# 使得Redis服务器可以跨网络访问
bind 0.0.0.0
# 日志文件
logfile "redis.log"
# 当前服务端口
port 16379
# 数据文件所在文件夹
dir "/data"
# 硬盘数据文件文件名
dbfilename "dump.rdb"
# 开启AOF模式
appendonly yes
# 保存数据的AOF文件名称
appendfilename "appendonly.aof"
# 从服务器密码
masterauth "wszgr"
# 主服务器密码,注意:有关slaveof的配置只是配置从服务器,主服务器不需要配置
requirepass "wszgr"
- 在/home/docker/redis/sentienl/redis/16380 下放:
# 使得Redis服务器可以跨网络访问
bind 0.0.0.0
# 日志文件
logfile "redis.log"
# 当前服务端口
port 16380
# 数据文件所在文件夹
dir "/data"
# 硬盘数据文件文件名
dbfilename "dump.rdb"
# 开启AOF模式
appendonly yes
# 保存数据的AOF文件名称
appendfilename "appendonly.aof"
# 从服务器密码
masterauth "wszgr"
# 主服务器密码,注意:有关slaveof的配置只是配置从服务器,主服务器不需要配置
requirepass "wszgr"
# 做为从服务连接主服务器
slaveof 192.168.47.150 16379
- 在/home/docker/redis/sentienl/redis/16380 下放:
# 使得Redis服务器可以跨网络访问
bind 0.0.0.0
# 日志文件
logfile "redis.log"
# 当前服务端口
port 16381
# 数据文件所在文件夹
dir "/data"
# 硬盘数据文件文件名
dbfilename "dump.rdb"
# 开启AOF模式
appendonly yes
# 保存数据的AOF文件名称
appendfilename "appendonly.aof"
# 从服务器密码
masterauth "wszgr"
# 主服务器密码,注意:有关slaveof的配置只是配置从服务器,主服务器不需要配置
requirepass "wszgr"
# 做为从服务连接主服务器
slaveof 192.168.47.150 16379
我这里默认16379是启动时候的主服务。
3> 准备sentinel.conf
哨兵的配置文件也是要准备三份的。
- 在/home/docker/redis/sentienl/sentinel/26379下放:
# 当前端口
port 26379
# 数据文件所在文件夹
dir "/data"
# 日志文件
logfile "sentinel.log"
# 设置master和slaves验证密码
sentinel deny-scripts-reconfig yes
# 哨兵监听的主服务器(配置的时候,后期主服务挂掉,自动寻找另外主服务)
#行尾最后的一个2代表什么意思呢?我们知道,网络是不可靠的,有时候一个sentinel会因为网络堵塞而误以为一个master redis已经死掉了,当sentinel集群式,解决这个问题的方法就变得很简单,只需要多个sentinel互相沟通来确认某个master是否真的死了,这个2代表,当集群中有2个sentinel认为master死了时,才能真正认为该master已经不可用了。
sentinel monitor mymaster 192.168.47.150 16379 2
# 30s内mymaster无响应,则认为mymaster宕机了
sentinel down-after-milliseconds mymaster 30000
# 指定了在执行故障转移时, 最多可以有多少个从服务器同时对新的主服务器进行同步
sentinel parallel-syncs mymaster 1
# 若哨兵在配置值内未能完成故障转移操作,则任务本次故障转移失败
sentinel failover-timeout mymaster 180000
# 定义服务的密码,mymaster是服务名称,wszgr是Redis服务器密码
sentinel auth-pass mymaster wszgr
- 在/home/docker/redis/sentienl/sentinel/26380下放:
将上面的配置文件port改为26380
- 在/home/docker/redis/sentienl/sentinel/26381下放:
将上面的配置文件port改为26381
4> 准备redis-compose.yml 文件
version: '3'
services:
redis-16379:
image: redis:4.0.14-buster
container_name: redis-16379
command: redis-server redis.conf
restart: always
ports:
- "16379:16379"
volumes:
- ./redis/16379:/data
redis-16380:
image: redis:4.0.14-buster
container_name: redis-16380
command: redis-server redis.conf
restart: always
ports:
- "16380:16380"
volumes:
- ./redis/16380:/data
depends_on:
- redis-16379
redis-16381:
image: redis:4.0.14-buster
container_name: redis-16381
command: redis-server redis.conf
restart: always
ports:
- "16381:16381"
volumes:
- ./redis/16381:/data
depends_on:
- redis-16379
sentinel-26379:
image: redis:4.0.14-buster
container_name: sentinel-26379
command: redis-sentinel sentinel.conf
restart: always
ports:
- "26379:26379"
volumes:
- ./sentinel/26379:/data
depends_on:
- redis-16379
sentinel-26380:
image: redis:4.0.14-buster
container_name: sentinel-26380
command: redis-sentinel sentinel.conf
restart: always
ports:
- "26380:26380"
volumes:
- ./sentinel/26380:/data
depends_on:
- redis-16379
sentinel-26381:
image: redis:4.0.14-buster
container_name: sentinel-26381
command: redis-sentinel sentinel.conf
restart: always
ports:
- "26381:26381"
volumes:
- ./sentinel/26381:/data
depends_on:
- redis-16379
三. 启动
进入到/home/docker/redis/sentienl目录下执行以下命令:
docker-compose -f redis-compose.yml up -d
然后就可以进行测试了。
四. 隐性问题说明
由于我这里采用的是docker的bridge方式,所以就存在一个网络连接问题,虽然看起来我使用了端口映射,并且连接了映射到主机的端口,但是依然存在这样的一个问题:
当主节点故障,哨兵就会切换一个从节点为主节点,但是从节点返回给哨兵的连接地址却是docker容器的地址,而不是宿主机的地址。那么如果我们不是在一台主机上部署测试,那么连接就已经出现问题了(另一台主机在没有专门处理的情况下是无法连接到这台主机的docker容器的。)。
所以如果你可以跨主机容器互联也是可以的,或者采用网络模式为host模式(bridge模式不行),这样直接使用宿主机的网络也可以。当然不选用docker的方式,而是直接启动redis只需要前面的redis和sentinel配置就可以了。