哨兵(sentinel)的主要作用为:当master节点发生故障时,众多slave节点中的一个可晋升为新的master节点来提供写服务,其余的slave节点仍然提供读服务,这种机制也别称为故障转移(failover)。主从复制+哨兵的架构模式如下所示:
配置
下面通过docker-compose演示如何在主从架构的基础上启用哨兵机制。修改docker-compose.yml文件内容,在volume中多加一个数据卷的映射,对应的配置文件为哨兵所需的.conf配置文件。
version: '3.1'services:redis1:image: daocloud.io/library/redis:5.0.7restart: alwayscontainer_name: redis1environment:- TZ=Asia/Shanghaiports:- 7001:6379volumes:- ./conf/redis1.conf:/usr/local/redis/redis.conf- ./conf/sentinel1.conf:/data/sentinel.confcommand: ["redis-server", "/usr/local/redis/redis.conf"]redis2:image: daocloud.io/library/redis:5.0.7restart: alwayscontainer_name: redis2environment:- TZ=Asia/Shanghaiports:- 7002:6379volumes:- ./conf/redis2.conf:/usr/local/redis/redis.conf- ./conf/sentinel2.conf:/data/sentinel.conflinks:- redis1:mastercommand: ["redis-server", "/usr/local/redis/redis.conf"]redis3:image: daocloud.io/library/redis:5.0.7restart: alwayscontainer_name: redis3environment:- TZ=Asia/Shanghaiports:- 7003:6379volumes:- ./conf/redis3.conf:/usr/local/redis/redis.conf- ./conf/sentinel3.conf:/data/sentinel.conflinks:- redis1:mastercommand: ["redis-server", "/usr/local/redis/redis.conf"]
并且在宿主机的conf目录下新建三个.conf配置文件。其中master对应的sentinel1.conf文件内容为:
# 哨兵需要后台启动daemonize yes# 指定master节点的ip和端口sentinel monitor master 127.0.0.1 6379 2# 哨兵每隔多久监听一次Redis架构sentinel down-after-milliseconds master 10000
在slave节点的哨兵配置文件中填写如下内容:
# 哨兵需要后台启动daemonize yes# 指定master节点的ip和端口sentinel monitor master master 6379 2# 哨兵每隔多久监听一次Redis架构sentinel down-after-milliseconds master 10000
然后使用docker-compose up -d启动容器,可以看到此时redis都已经正常启动,但是哨兵并没有启动。
接着需要分别进入到三个Redis容器内部,使用redis-sentinel sentinel1.conf、redis-sentinel sentinel2.conf、redis-sentinel sentinel2.conf分别启动哨兵。退出容器后,再次查看宿主机的sentinel1.conf文件可以看到如下内容:
至此,带有哨兵机制的主从架构就启动完毕。
原理
哨兵具有如下的功能:
- 监控:哨兵会不断的检查master节点和slave节点是否正常运作
- 自动故障转移:当哨兵发现master节点无法正常工作,它会将对应的slave节点中的一个晋升为master节点。即使出错的master节点后续恢复正常,它也只能作为新master节点的slave
- 配置提供者:客户端初始化时,通过哨兵来获取当前Redis服务的master节点配置
- 通知:哨兵可以将故障转移的结果发送给客户端
其中,当master节点发生故障时,新的master节点的选择原则如下:
- 在失效主服务器属下的从服务器当中, 那些被标记为主观下线、已断线、或者最后一次回复 PING 命令的时间大于五秒钟的从服务器都会被 淘汰
- 在失效主服务器属下的从服务器当中, 那些与失效主服务器连接断开的时长超过 down-after 选项指定的时长十倍的从服务器都会被 淘汰
- 在 经历了以上两轮淘汰之后 剩下来的从服务器中, 我们选出 复制偏移量(replication offset)最大 的那个 从服务器 作为新的主服务器;如果复制偏移量不可用,或者从服务器的复制偏移量相同,那么 带有最小运行 ID 的那个从服务器成为新的主服务器
那么,哨兵是如何感知到master节点出现故障了呢? 哨兵节点会定期的向master节点发送心跳包判断其是否存活,称为PING。当某个哨兵发现master发生了故障,它将其标记为主观不可用状态,然后将其发送给其他的哨兵节点。如果确认master故障的哨兵节点个数超过了设置的阈值,则认为该master客观不可用,进行故障转移的流程。
