主从库集群模式下,如果从库挂了,主库还可以接受客户端的读写请求。但是如果主库挂了,读请求还可以继续,写请求就不被允许了。
如果主库挂了,那就会从从库中选择一个出来作为主库。
这里有三个问题:
1 主库真的挂了么?
2 该选择哪个主库作为从库?
3 如何把主库的信息同步给客户端?
随着上面的三个问题引出了redis哨兵机制,哨兵机制是主从库之间切换的关键机制。他有效的解决了主从复制下故障转移的问题。
哨兵机制的任务: 监控,选主,通知。他是一个运行在特殊模式下的redis进程,他和主从库一起运行。
监控指的是哨兵在运行过程中,周期性的给所有的主从库发送ping命令,检测他们是否仍然在线存活。如果哨兵没有在规定时间内获取到ping命令的回调,则哨兵会把这个节点标记为下线状态。主库的话就回开启主从库切换模式。 哨兵会按照策略从从库里选择一个实例出来作为主库。哨兵会把新主库的信息发送给其他从库,其他从库获取到主库信息后执行reolicaof命令,和主库进行连接,并复制数据。哨兵也会把主库的信息发送给客户端,以后客户端的请求都打到主库上。
哨兵是如何实现判断主库下线的?
哨兵会通过ping命令查看主从节点的响应状态,从而判断节点的存活情况。如果ping响应超时,则会被标记为下线状态。如果是从库直接下线就行,如果是主库,则要开启主从切换,后续的选主和通知都会带来计算机的计算和通信开销。 但是哨兵也会误判,多数情况是因为哨兵网络阻塞和主库压力。为了防止发生误判引入了哨兵集群,多个哨兵实例一起判断,避免单个哨兵实例因为自身网络问题而发生误判,也就是少数服从多数。
如何选定新的主库?
从库筛选条件:必须是存活的,仍然运行的。接着判断他的网络连接状态,如果该从库和主库一直断连,并且断连的次数超过了一定的阈值,那么这个从库就显然不适合做主库了。可以配置down after millionsecond,该参数是主从库连接的最大超时时间。如果这个时间内主库都没有收到从库的响应,则该从库就被认识是失联了,如果断连此处超过10次就说明网络不行,不适合做主库。
接下来要给剩余的从库打分。判断标准为 从库优先级,从库复制进度,从库ID号。主要在一轮有从库得分最高,则该从库就是主库了,没有的话就继续下一轮。
从库优先级:可以给不同的从库设置优先级,slave-priority。比如可以给内存大的实例设置优先级高点,那选主库时默认就是该从库。
从库复制进度:要是某个从库的复制slave-repl-offset,更靠近主库的master-repl-offset,则该从库就是备用主库了。
slave-repl-offset是从库同步主库的复制进度。master-repl-offset是主库同步给从库的进度。如果复制进度都相等,则开启第三轮。
从库ID号:如果上面两轮都没选到主库,这一轮会从从库里选取id号小的,即为主库。