Redis 集群搭建(三):Docker 部署 Redis + Sentinel 高可用集群
前言
主从相关配置讲解:Redis 集群搭建(二):Redis主从同步与读写分离
PS:文件夹结构方面做了下调整
配置说明:
redis-master: redis 主库,挂载文件都放在 /data/redis/sentinel/master
下面,端口号 6379
,对应 Sentinel
端口 26379
redis-slave1: redis 从库1,挂载文件都放在 /data/redis/sentinel/slave1
下面,端口号 6380
,对应 Sentinel
端口 26380
redis-slave2: redis 从库2,挂载文件都放在 /data/redis/sentinel/slave2
下面,端口号 6381
,对应 Sentinel
端口 26381
每个文件夹都包含以下目录:
- conf: 配置文件文件夹
- data: 主要文件挂载,包含持久化文件之类的
- logs: 日志文件目录,这会把日志文件夹也挂出来,好看一些打印
下面是 master 文件夹的截图
建议
- 由于
Sentinel 启动
,故障切换
,日志文件创建
等情况均需要修改配置文件,因此一定要给文件读写权限,因此启动前先chmod 777 -R /data/redis/
给所有文件夹配置好权限 - 由于不管是
Redis
还是Sentinel
的配置文件均会出现被修改
的情况,因此建议启动前先对原文件备份
Sentinel 至少要有 3 及以上,每个 Sentinel 就是一个集群,因此正常情况下,一套主从对应一个 Sentinel 即可,这里由于资源有限,因此一个 Redis 对应一个 Sentinel,他们之间的数据,以主从复制的方式进行同步
官方译文
什么是 Sentinel?
Redis Sentinel 为 Redis 提供了高可用
解决方案。实际上这意味着使用 Sentinel 可以部署一套 Redis,在没有人为干预的情况下去应付各种各样的失败事件。
Sentinel 优点
- 监控: Sentinel 会去自动监控你的主从实例是否再正常运行
- 通知: Sentinel 提供了
API
,在实例出现问题时可以通知管理员,或者其他程序 - 自动故障转移: 如果一个主节点出现了问题,可以通过将从节点升级为主节点,这时候原先的主节点重启则会作为从节点接入(会自动去改配置文件,因此配置文件能看到修改后的配置)
- 配置提供者: 后台只需要连接 Sentinel 即可,不需要考虑切换后配置变更
Redis 配置文件
redis.conf 文件,我统一放在 conf
目录下
master
protected-mode: 关闭保护模式,因为开启情况下容器间 Redis 与 Sentinel 的通信似乎会存在问题,体现在故障切换后主节点找不到从节点的情况
masterauth: 给主节点也设置连接主节点所需的密码,因为故障转移后,会以从节点的身份接入
bind 0.0.0.0: 也是容易出问题的点,建议先 0.0.0.0,等集群都成功后,如有需要再做限制
# redis 端口号
port 6379
# RDB 持久化,快照保存频率
# 900秒内,如果超过1个key被修改,则发起快照保存
# 300秒内,如果超过10个key被修改,则发起快照保存
# 60秒内,如果1万个key被修改,则发起快照保存
save 900 1
save 300 10
save 60 10000
# 在进行数据镜像备份时,是否启用rdb文件压缩手段,默认为yes。
rdbcompression yes
# 解决 Redis 被配置为保存数据库快照,但它目前不能持久化到硬盘。用来修改集合数据的命令不能用。
stop-writes-on-bgsave-error no
# 开启 AOF 持久化
appendonly yes
# 设置密码
requirepass "111111"
# 开启保护模式
protected-mode no
# 指定 redis 日志文件地址
logfile "/redis/logs/redis.log"
# 设置主库的密码,挂了切换,也需要密码
masterauth "111111"
# 不限制访问
bind 0.0.0.0
slave
由于两个从库配置除了端口号都是一样的,因此就放一份在这
该注意的点都和 master 一样,其他没有什么特别的,配置好主从即可
# redis 端口号
port 6380
# RDB 持久化,快照保存频率
# 900秒内,如果超过1个key被修改,则发起快照保存
# 300秒内,如果超过10个key被修改,则发起快照保存
# 60秒内,如果1万个key被修改,则发起快照保存
save 900 1
save 300 10
save 60 10000
# 在进行数据镜像备份时,是否启用rdb文件压缩手段,默认为yes。
rdbcompression yes
# 解决 Redis 被配置为保存数据库快照,但它目前不能持久化到硬盘。用来修改集合数据的命令不能用。
stop-writes-on-bgsave-error no
# 开启 AOF 持久化
appendonly yes
# 设置密码
requirepass "111111"
# 开启保护模式
protected-mode no
# 设置主库的密码
masterauth "111111"
# 设置从库只读
slave-read-only yes
# redis 日志文件地址
logfile "/redis/logs/redis.log"
# 不限制访问
bind 0.0.0.0
# 指定作为 master 的 redis
slaveof 127.0.0.1 6379
Sentinel 配置文件
sentinel.conf 文件,同样放在 conf
目录下,每个 redis
对应一个 Sentinel
master
主从的配置文件是一模一样的,因为都只需要配置主节点的信息即可,至于从节点 Sentinel 会自动根据 Redis 的主从关系去获取无需配置。
假如你有多个主节点,则每个 Sentinel 中都要配置所有主节点的信息,具体的也可以参考官方译文中的例子
# 关闭保护模式
protected-mode no
# 不限制访问
bind 0.0.0.0
# 配置监听的主服务器
# 这里sentinel monitor代表监控
# redis-master 代表服务的名称,可以自定义
# IP + Port 代表监控的主服务器
# 1 代表只有一个或一个以上的哨兵认为主服务器不可用的时候,才会进行故障转移
# 比如,我这里的例子一共是 3 个 sentinel,当主的挂了,剩下两个只要有一个认为主的出问题,即可转移
sentinel monitor redis-master 127.0.0.1 6379 1
# 日志文件路径指定
logfile "/redis/logs/sentinel.log"
# 主 redis 密码(如果主从密码不一样,那就用 bind 或者 关闭保护模式)
sentinel auth-pass redis-master 111111
# redis 在一定时间内无法应答哨兵,视为下线,默认为30000(30秒)
sentinel down-after-milliseconds redis-master 5000
# 指定故障切换允许的毫秒数,超过这个时间,就认为故障切换失败,默认为3分钟
sentinel failover-timeout redis-master 60000
# 指定可以有多少个Redis服务同步新的主机
# 一般而言,这个数字越小同步时间越长
# 越大,则对网络资源要求越高
sentinel parallel-syncs redis-master 1
启动
启动顺序: 主节点 Redis ➡ 从节点 Redis ➡ Sentinel
启动 Redis
解释下每行什么意思,从 端口号那行开始
- 端口号映射,前面是
Redis
的,后面是Sentinel
的 - 挂载配置文件到
Redis
- 挂载主要文件,包含持久化文件之类的
- 挂载日志文件(不管是 redis 还是 sentinel 我都指定了对应的日志目录)
- 容器启动后执行命令,使用我们自己挂载的
Redis
配置文件启动Redis
docker run -d --name redis-master \
-p 6379:6379 -p 26379:26379 \
-v /data/redis/sentinel/master/conf:/redis/conf \
-v /data/redis/sentinel/master/data:/data \
-v /data/redis/sentinel/master/logs:/redis/logs redis \
redis-server /redis/conf/redis.conf
docker run -d --name redis-slave1 \
-p 6380:6380 -p 26380:26379 \
-v /data/redis/sentinel/slave1/conf:/redis/conf \
-v /data/redis/sentinel/slave1/data:/data \
-v /data/redis/sentinel/slave1/logs:/redis/logs redis \
redis-server /redis/conf/redis.conf
docker run -d --name redis-slave2 \
-p 6381:6381 -p 26381:26379 \
-v /data/redis/sentinel/slave2/conf:/redis/conf \
-v /data/redis/sentinel/slave2/data:/data \
-v /data/redis/sentinel/slave2/logs:/redis/logs redis \
redis-server /redis/conf/redis.conf
启动 Sentinel
直接对容器内执行命令
docker exec -it redis-master /bin/bash -c 'redis-sentinel /redis/conf/sentinel.conf'
docker exec -it redis-slave1 /bin/bash -c 'redis-sentinel /redis/conf/sentinel.conf'
docker exec -it redis-slave2 /bin/bash -c 'redis-sentinel /redis/conf/sentinel.conf'
成功
看下 logs 下面 sentinel.log
日志
查看 Sentinel 信息,Sentinel 端口 26379
# 直接在容器内执行,所以 127.0.0.1,端口号都是 26379,只是用 docker 改了映射而已
# 每个 redis 容器都可以执行,结果一样的
docker exec -it redis-master /bin/bash -c 'redis-cli -h 127.0.0.1 -p 26379'
# 查看所有主节点信息
sentinel masters
PS:exit 命令可以退出 Sentinel
查看主节点下所有子节点信息
# 查看主节点下所有子节点信息
sentinel slaves redis-master
故障转移
通过命令让,redis-master
睡眠 60s
来模拟宕机
docker exec -it redis-master /bin/bash -c 'redis-cli -a 111111 -p 6379 DEBUG sleep 60'
看下主库的 Sentinel
日志,我直接复制出来翻译下
# 这个哨兵认为 master 挂了
17:X 15 Apr 2020 03:59:42.794 # +sdown master redis-master 118.25.215.105 6379
# +odown (object down)表示这个主节点已经至少有 1 个哨兵认为它 down 了
#(达到了法定票数1)从而进入了客观down状态
17:X 15 Apr 2020 03:59:42.794 # +odown master redis-master 118.25.215.105 6379 #quorum 1/1
# 配置文件新版本
17:X 15 Apr 2020 03:59:42.794 # +new-epoch 1
# 开始进行故障转移
17:X 15 Apr 2020 03:59:42.794 # +try-failover master redis-master 118.25.215.105 6379
# 选择一个哨兵作为 leader,后面是哨兵投票
17:X 15 Apr 2020 03:59:42.800 # +vote-for-leader 7ee8f26df414a385d32d499f6579dbded312eacd 1
17:X 15 Apr 2020 03:59:42.808 # 131b744208db8e78dec5792dc1e4ca872ded3710 voted for 7ee8f26df414a385d32d499f6579dbded312eacd 1
17:X 15 Apr 2020 03:59:42.809 # 5ef10f99a9a921243825125dda4473cd5ff08a14 voted for 7ee8f26df414a385d32d499f6579dbded312eacd 1
# 选中 leader
17:X 15 Apr 2020 03:59:42.891 # +elected-leader master redis-master 118.25.215.105 6379
# 开始选择一个 slave 作为 master
17:X 15 Apr 2020 03:59:42.891 # +failover-state-select-slave master redis-master 118.25.215.105 6379
# 选中 6380 的 slave 作为 master
17:X 15 Apr 2020 03:59:42.974 # +selected-slave slave 118.25.215.105:6380 118.25.215.105 6380 @ redis-master 118.25.215.105 6379
# 发送 slave no one 命令,即不再作为从节点
17:X 15 Apr 2020 03:59:42.974 * +failover-state-send-slaveof-noone slave 118.25.215.105:6380 118.25.215.105 6380 @ redis-master 118.25.215.105 6379
# 等待升级为主节点
17:X 15 Apr 2020 03:59:43.050 * +failover-state-wait-promotion slave 118.25.215.105:6380 118.25.215.105 6380 @ redis-master 118.25.215.105 6379
# 成功升级为主节点
17:X 15 Apr 2020 03:59:43.873 # +promoted-slave slave 118.25.215.105:6380 118.25.215.105 6380 @ redis-master 118.25.215.105 6379
# 故障转移,更改 6379 这个配置文件为 从节点
17:X 15 Apr 2020 03:59:43.874 # +failover-state-reconf-slaves master redis-master 118.25.215.105 6379
# 故障转移,更改 6381 这个配置重新设置主节点
17:X 15 Apr 2020 03:59:43.929 * +slave-reconf-sent slave 118.25.215.105:6381 118.25.215.105 6381 @ redis-master 118.25.215.105 6379
# 从节点配置新主完成,但同步过程尚未完成
17:X 15 Apr 2020 03:59:44.516 * +slave-reconf-inprog slave 118.25.215.105:6381 118.25.215.105 6381 @ redis-master 118.25.215.105 6379
# 从节点与新主同步完成
17:X 15 Apr 2020 03:59:45.575 * +slave-reconf-done slave 118.25.215.105:6381 118.25.215.105 6381 @ redis-master 118.25.215.105 6379
#故障转移成功。所有从节点配置完成
17:X 15 Apr 2020 03:59:45.630 # +failover-end master redis-master 118.25.215.105 6379
# 主配置新IP和地址是配置更改后指定的IP地址
17:X 15 Apr 2020 03:59:45.630 # +switch-master redis-master 118.25.215.105 6379 118.25.215.105 6380
# 下面是从节点信息,就和刚启动时一样
17:X 15 Apr 2020 03:59:45.631 * +slave slave 118.25.215.105:6381 118.25.215.105 6381 @ redis-master 118.25.215.105 6380
17:X 15 Apr 2020 03:59:45.631 * +slave slave 118.25.215.105:6379 118.25.215.105 6379 @ redis-master 118.25.215.105 6380
# 因为主的挂了,转为从的了,但是主的还未启动,所以任务这个主节点挂机
17:X 15 Apr 2020 03:59:50.653 # +sdown slave 118.25.215.105:6379 118.25.215.105 6379 @ redis-master 118.25.215.105 6380
# 主节点 sleep 结束,重新接入,认为这个从节点不再挂机
17:X 15 Apr 2020 04:00:37.486 # -sdown slave 118.25.215.105:6379 118.25.215.105 6379 @ redis-master 118.25.215.105 6380
可以用之前的方式看下现在主节点的信息,可以看到主节点已经变成 6380
如果你去看你的配置文件,你会发现配置文件都已经被更改
SpringBoot 连接 Sentinel
SpringBoot 整合 Redis 及 Redis 工具类
修改 Redis 配置
#本地/测试服配置
spring:
#Redis配置
redis:
# Redis 连接密码
password: 111111
# sentinel 集群配置
sentinel:
# Sentinel 服务的名称
master: redis-master
nodes: 127.0.0.1:26379,127.0.0.1:26380,127.0.0.1:26381
jedis:
pool:
# 连接池最大连接数(使用负值表示没有限制)
max-active: 200
# 连接池最大阻塞等待时间(使用负值表示没有限制)
max-wait: -1ms
# 连接池中的最大空闲连接
max-idle: 8
# 连接池中的最小空闲连接
min-idle: 0
# 连接超时时间(毫秒)
timeout: 1000ms