1.基本概述
对于redis主从复制,一旦master节点宕机了,从机依旧是从机,只支持读操作,对于需要写操作的业务无法处理。
为了解决这个问题,就有了redis哨兵(sentinel),它可以监控master节点是否宕机,如果master节点宕机,就通过投票数决定新主库master。
不过因为sentinel自己也可能宕机,所以一般建议使用三台以上redis哨兵(sentinel)监控。而且sentinel采取奇数台,防止有些sentinel无法连接到master导致误切换。
Sentinel作用:
- 监视:Sentinel不断检查主从redis库是否正常。
- 通知:Sentinel可以通过API通知被监视的Redis实例出现了问题。
- 自动故障转移:如果一个主服务器没有像预期的那样工作,Sentinel可以启动一个故障转移过程,其中一个副本被提升为主服务器,其他额外的副本被重新配置为使用新的主服务器,并且使用Redis服务器的应用程序在连接时被告知使用的新地址。
- 配置提供者:客户端连接到哨兵以获得当前负责给定服务的Redis主服务器的地址。如果发生故障转移,哨兵将报告新的地址。

2.配置示例
因为哨兵(sentinel)监控master和slave,所以其配置可以参考我的博客
redis主从复制 – Dreams (tanjy.site)
哨兵(sentinel)的配置文件在redis安装目录下的sentinel.conf:

我们将其拷贝到工作目录下,原文件留作备份:
cp sentinel.conf /myredis/

查看配置参数
vim sentinel.conf
安全保护模式

端口

是否允许以后台启动

日志目录

工作目录

同意故障迁移的法定票数。设置要监控的master服务器,quorum表示最少有几个哨兵认可客观下线,达到要求后就是哨兵日志里会检测到odown。

要连接到的master密码

pid文件保存路径

指定多少毫秒之后,主节点没有应答哨兵,此时哨兵主观上认为主节点下线,也就是哨兵日志里会检测到sdown的时间。默认30秒

表示允许并行同步的slave个数,当Master挂了后,哨兵会选出新的Master,此时,剩余的slave会向新的master发起同步数据

故障转移的超时时间,进行故障转移时,如果超过设置的毫秒,表示故障转移失败

配置当某一事件发生时所需要执行的脚本

客户端重新配置主节点参数脚本

因为我没有那么多主机,所以在同一台主机上开3个服务,实际也只要改为对应端口和对应ip即可
我们这里模造创建3个文件
第一个文件
vim sentinel26379.conf
配置如下
bind 0.0.0.0 daemonize yes protected-mode no port 26379 logfile "/myredis/log/sentinel26379.log" pidfile /var/run/redis-sentinel26379.pid dir /myredis sentinel monitor mymaster 8.134.133.76 6379 2 sentinel auth-pass mymaster 123456
第二个文件
vim sentinel26380.conf
配置如下
bind 0.0.0.0 daemonize yes protected-mode no port 26380 logfile "/myredis/log/sentinel26380.log" pidfile /var/run/redis-sentinel26380.pid dir /myredis sentinel monitor mymaster 8.134.133.76 6379 2 sentinel auth-pass mymaster 123456
第三个文件
vim sentinel26381.conf
配置如下
bind 0.0.0.0 daemonize yes protected-mode no port 26381 logfile "/myredis/log/sentinel26381.log" pidfile /var/run/redis-sentinel26381.pid dir /myredis sentinel monitor mymaster 8.134.133.76 6379 2 sentinel auth-pass mymaster 123456
这里先按我的博客配置好master节点和slave节点的配置文件
redis主从复制 – Dreams (tanjy.site)
然后这里还要更改一些配置
打开master节点的redis配置文件
vim redis6379.conf
加入密码,这里是master可能会变成slave,要加上密码。否则会报master_link_status:down。

slave节点就

启动3台redis示例:
redis-server /myredis/redis6379.conf
redis-server /myredis/redis6380.conf
redis-server /myredis/redis6381.conf
查看主从关系
info replication

启动3个哨兵
redis-sentinel /myredis/sentinel26379.conf
redis-sentinel /myredis/sentinel26380.conf
redis-sentinel /myredis/sentinel26381.conf
主从复制正常


查看哨兵日志
vim /myredis/log/sentinel26379.log

注意看这3行

再去查看哨兵的配置文件,发现它自动写入了一些配置
vim /myredis/sentinel26379.conf

模拟主机master服务挂了,也就是6379端口的redis服务

这时redis从节点会经过投票选出新的master节点,需要时间,所以可能暂时连接不到,稍等即可获取数据。

这时可以看到redis6381成为了新的master节点

而它的redis配置文件也发生了变化
vim /myredis/redis6381.conf

查看哨兵日志,可以看到投票选出了6381,sdown是单个sentinel自己主观检测到的关于master的状态,ping心跳后,在一定时间内没有收到合法的回复,就达到了sdown的条件。多个哨兵达成一致意见j就达到odown,就认为一个master客观上已经宕掉。
vim /myredis/log/sentinel26379.log

这时再重启redis6379服务,稍等一会,查看主从消息,可以看到变成了slave节点
redis-server /myredis/redis6379.conf
redis-cli -a 123456 -p 6379
info replication

这时的redis6379配置文件会被写入新的数据
vim /myredis/redis6379.conf

而哨兵日志也加入几行

回顾刚刚更改master节点时,如果不稍等,会出现两个错误:
pipe就是管道,从文件或网络套接字读取数据。当该管道从另一端突然关闭时,会发生数据突然中断,就是broken,对于socket来说,可能是网络被拔出或另一端的进程崩溃。这个异常就是客户端读取超时而关闭了连接,这时候服务器端再向客户端已经断开的连接写数据时就发生了broken pipe异常!这对于服务端无影响。


3.执行流程
1.sdown
master下线,sentinal发送PING心跳后,在一定时间内(配置文件配置down-after-milliseconds参数)没有收到合法的回复,就达到了sdown的条件。

2.odown
经过一定数量(配置文件quorum参数)的sentinal判断,才能达到odown状态。

3.选举leader
一个哨兵被选举出来,称为leader,由它启动故障转移,这样就不会在少数情况下执行故障转移。选举算法采用Raft算法,即先到先得,当前哨兵A发送请求投票给其他哨兵如哨兵B,如果哨兵B没有投票给其他哨兵,就同意投票。

查看日志

4.leader哨兵判断master
先在redis配置文件中,判断slave-priority或者replica-priority优先级最高的从节点(数字越小优先级越高)

如果优先级相同就判断复制偏移位置offset最大的从节点,复制偏移位置offset就是从节点复制了主节点多少条数据。越多越好。
如果还相同就使用ASCII码最小的Run ID的从节点。
5.新的master节点出现。
Sentinel leader会对选举出的新master执行slaveof no one操作,将其提升为master节点Sentinel leader向其它slave发送命令,让剩余的slave成为新的master节点的slave。原master重新上线也会成为新的master节点的slave。
注意:
哨兵和主从复制,并不能保证数据零丢失。


