前面我们讲解了redis的主从复制原理及配置。假设一种场景,我们的master服务器宕机了,只有去手动的切换slave为master服务器,需要人工干预,还会造成一段时间内服务不可用。那我们可以考虑redis的哨兵模式(Sentinel)。
首先要从redis的主从模式说起,redis的主从模式就是把上图的所有的哨兵去掉,就变成了主从模式,主从模式是主节点负责写请求,然后异步的同步给从节点,然后从节点负责读请求,所以在主从架构中redis每个节点保存的数据是相同的,只是数据的同步可能会有一点延迟,那考虑到高可用性,如果主节点挂了,是没有一个自动选主的机制的,需要人工来指定一个节点为主节点,然后再恢复成主从结构,所以其实也是不能做到高可用。
为了解决主从模式不能高可用的问题,就发明了哨兵模式,所谓的哨兵模式,就是在原来的主从架构的基础上,又搞了一个集群,哨兵集群,这个集群会监控redis集群的主节点和从节点的状态,如果发现主节点挂了,就会重新在从节点中选出来一个作为主节点,从而做到高可用。
那哨兵本身是一个集群,那这个集群之间是怎么通信的呢?哨兵模式既然可以监控redis集群,做到故障转移,哨兵集群又是怎么监控redis集群的呢?下面就分析这两个问题:
哨兵集群中的每个节点都会启动三个定时任务
1、每个Sentinel以每秒钟一次的频率向它所知的Master,Slave以及其他 Sentinel 实例发送一个 PING 命令。 2、如果一个实例(instance)距离最后一次有效回复 PING 命令的时间超过 down-after-milliseconds 选项所指定的值, 则这个实例会被 Sentinel 标记为主观下线。 3、如果一个Master被标记为主观下线,则正在监视这个Master的所有 Sentinel 要以每秒一次的频率确认Master的确进入了主观下线状态。 4、当有足够数量的 Sentinel(大于等于配置文件指定的值)在指定的时间范围内确认Master的确进入了主观下线状态, 则Master会被标记为客观下线 。 5、在一般情况下, 每个 Sentinel 会以每 10 秒一次的频率向它已知的所有Master,Slave发送 INFO 命令 。 6、当Master被 Sentinel 标记为客观下线时,Sentinel 向下线的 Master 的所有 Slave 发送 INFO 命令的频率会从 10 秒一次改为每秒一次 。 7、若没有足够数量的 Sentinel 同意 Master 已经下线, Master 的客观下线状态就会被移除。 若 Master 重新向 Sentinel 的 PING 命令返回有效回复, Master 的主观下线状态就会被移除。
这个就是上面介绍的第一个定时任务做的事情,当sentinel节点向master发送一个PING命令,如果超过own-after-milliseconds(默认是30s,这个在sentinel的配置文件中可以自己配置)时间都没有收到有效回复,不好意思,我就认为你挂了,就是说为的主观下线(SDOWN),修改其flags状态为SRI_S_DOWN。
要了解什么是客观下线要先了解几个重要参数
到现在为止,已经知道了master客观下线,那就需要一个sentinel来负责故障转移,那到底是哪个sentinel节点来做这件事呢?需要通过选举实现,具体的选举过程如下:
通过上面的介绍,已经有了领头sentinel,下面就是要做故障转移了,故障转移的一个主要问题和选择领头sentinel问题差不多,到底要选择哪一个slaver节点来作为master呢?按照我们一般的常识,我们会认为哪个slaver中的数据和master中的数据相识度高哪个slaver就是master了,其实哨兵模式也差不多是这样判断的,不过还有别的判断条件,详细介绍如下:
在进行选择之前需要先剔除掉一些不满足条件的slaver,这些slaver不会作为变成master的备选
选主过程
由于只有主节点负责写数据,如果有大量的写请求的时候,主节点负载太高,有挂掉的风险
解决办法:使用cluster模式(后面的章节会讲到)
接下来会配置3个哨兵和1主2从的Redis服务器来演示这个过程。
服务类型 | 是否主服务器 | IP地址 | 端口 |
---|---|---|---|
redis | 是 | 127.0.0.1 | 6379 |
redis | 否 | 127.0.0.1 | 6380 |
redis | 否 | 127.0.0.1 | 6381 |
sentinel | - | 127.0.0.1 | 26379 |
sentinel | - | 127.0.0.1 | 26380 |
sentinel | - | 127.0.0.1 | 26381 |
上一章_点这里_我们配置了主从复制的redis.conf的文件夹,这里我们就不再讲述了:
# 使得Redis服务器可以跨网络访问 bind 0.0.0.0 # 设置密码 requirepass "123456" # 指定主服务器,注意:有关slaveof的配置只是配置从服务器,主服务器不需要配置 slaveof 127.0.0.1 6379 # 主服务器密码,注意:有关slaveof的配置只是配置从服务器,主服务器不需要配置 masterauth 123456
上述内容主要是配置Redis服务器,从服务器比主服务器多一个slaveof的配置和密码。
配置3个哨兵,每个哨兵的配置都是一样的。在Redis安装目录下有一个sentinel.conf文件,copy一份进行修改:
# 禁止保护模式 关闭了保护模式,便于测试。 protected-mode no # 配置监听的主服务器,这里sentinel monitor代表监控,mymaster代表服务器的名称,可以自定义,127.0.0.1代表监控的主服务器,6379代表端口,2代表只有两个或两个以上的哨兵认为主服务器不可用的时候,才会进行failover操作。 sentinel monitor mymaster 127.0.0.1 6379 2 # sentinel author-pass定义服务的密码,mymaster是服务名称,123456是Redis服务器密码 # sentinel auth-pass <master-name> <password> sentinel auth-pass mymaster 123456
启动redis服务器和sentinel服务
# 启动Redis服务器进程 ./redis-server ./myredis/redis.conf # 启动哨兵进程 ./redis-sentinel ./myredis/sentinel.conf --sentinel
可以看到,6379已经是6380、6381的master服务器。
手动宕机主服务器6379,看看发生了什么变化,待续…