前言
Redis的主从、哨兵模式、集群模式,在前文中都已经有了详细的搭建流程,可谓是手把手教程,也得到了很多朋友的喜欢。由于前文偏向于应用方面,就导致了理论知识的匮乏,我们可能会用了,但却不明所以,所以今天,博主就通过接下里的几篇博客给大家分别讲解Redis哨兵机制的原理和集群模式下的原理。
导读
在开始讲解之前,博主把前面几篇博客的地址放在这里供大家去翻阅:
Java开发 - 让你少走弯路的Redis的主从复制
Java开发 - 让你少走弯路的Redis主从实现单节点哨兵模式
Java开发 - 让你少走弯路的Redis集群搭建
在这三篇Redis内容中,已经从主从到哨兵再到集群给大家一步步做了详细的应用讲解,如果你对Redis的使用还存在一定的问题的话不妨去看看,兴许会有一些新的收获。
多哨兵模式的疑问
在 Redis集群搭建这篇博客的末尾,博主有这么一段话,见下方:
一个sentinel哨兵大家会了,但是多个sentinel哨兵怎么让他们彼此之间也能监听到呢?诚如博主所说,多个哨兵和一个哨兵的使用方法是一样的,只需要监听主节点,其他的,哨兵会自动完成。
不信?博主专门搭建了一个多哨兵的Redis,我们来看看。
这是我的Redis和Sentinel配置文件:
Redis架构如下:
就是简单的一主二从。
Sentinel的架构如下:
我们分别启动三个Redis和三个Sentinel:
至于配置,就和我博客里面的一摸一样,大家可以照着自己做,这里是演示多个sentinel的工作情况。
如果你要是自己看了报文,你就会发现细节:
这个26380的:
这是26379的:
唯一配置变的地方还真有一个,就是在sentinel的配置文件中:
sentinel monitor mymaster 127.0.0.1 6379 2
监听的主节点后面的数字变了,一个sentinel的时候写1,三个sentinel的时候要过半的sentinel认为主节点挂掉才能故障转移和切换,三个,那过半就写2了,如果你有更多sentinel,这个数字也要改变。当然,你写1也行,但可能出现误判的情况。
测试关闭主节点:
已关闭,此时看从节点:
出现了短暂的连接被拒绝的情况,此时我们发现sentinel没有任何变化,大概也就是几秒钟的样子,变化产生了:
此时去看其他的sentinel节点,会发现有明显的选举过程:
此时如果把sentinel6379下线掉之后,会发生什么?我们试试;
大概在几秒后,sentinel做出了反应,同时输出26379离线的通知,但是Redis那边没有任何的反应,这个正常,毕竟不是redis监控哨兵,是吧?
到这里,还需要博主继续下去吗?一切已经说明了问题。 多哨兵的模式按照博主的方式放心用就行了。
到此,多sentinel使用也算是给大家做了演示,加油哦!
Redis哨兵工作原理
从上面的测试来看,当主节点发生故障挂掉之后,大概时间是18s,sentinel感知到故障,执行自动的故障迁移,当然,这个时间是可以自己调整的。为了了解这种工作机制,我们有必要来了解下sentinel的三种定时监控任务。
INFO指令获得最新节点拓扑图
每个sentinel每隔10s就会向主节点发送INFO命令,然后获取整个Redis节点的拓扑图,这也是为什么,当有节点退出,或有节点加入时,sentinel能极快的感知到拓扑图变化的原因,也是我们只需要指定主节点而不需要指定从节点的原因。
此时还没有完,sentinel通过INFO命令感知到拓扑图后,就发现了主节点下的其他从节点,等到下个10s后,就会同时向主节点和从节点发送INFO命令,以达到监听所有redis节点的目的。
此处应该有图,但是我好懒,我觉得大家应该明白了这个道理了吧?
通过发布订阅获得Master节点和其他Sentinel的信息
每个sentinel间隔2s会向指定频道发送自己关于主节点是否正常的判断,同时还包含当前sentinel节点的信息,其他sentinel通过订阅这个频道就可以达到信息共享的目的,此时就可以判断master节点是不是活的,sentinel节点是不是活的。
解释下关于订阅频道的理解,对于监视同一个主节点的多个Sentinel来说,一个Sentinel发送的信息会被其他Sentinel接收到,这其他Sentinel会根据这些信息来做出对master和对应sentinel的判断。我们可以认为他们是通过主节点达到数据共享的。
我们暂时就理解到这里,不再做更多深层的源码方面的理解。
但当博主打开了sentinel26379的配置文件,偶然在最末位发现了这几段自动生成的配置,似乎打开了新世界的大门:
known- sentinel就是知道另一个sentinel,这都是自动完成的,其原理博主不得,但猜测是通过Master节点完成的数据的共享,上图似乎也是一个对我们假设的印证。
PING指令⼼跳检测
每个Sentinel每隔1秒会向所有节点( Sentinel 节点、 Master 节点、 Slave 节点)发送PING指令来进⾏⼼跳检测。
选举过程
- 在上面的案例中,当一个sentinel节点认为Master不可用时,会进行主观下线,但并不会真的下线,而是继续通过sentinel is-masterdown-by-addr指令来获取其他sentinel对Master节点的判断,如果最终判断的值达到了我们设置的quorum值,Master节点就被判定为客观下线;
- Leader Sentinel(每个发现master服务器进入下线的sentinel都可以要求其他sentinel选自己为sentinel的leader,选举是先到先得)会从原来的Master的Slave中选出一个做为新的主节点
- 首先过滤所有主观下线的节点;
- 选择slave-priority最高的节点,有的话返回,没有的话继续;
- 选择复制偏移量offset最⼤的节点,有的话返回,没有的话继续;
- 选择run_id(服务器运⾏ ID)最⼩的节点,
- 最终选出一个节点,Leader Sentinel节点会通过 SLAVEOF NO ONE命令,让选择出来的Slave变为新的Master,再通过SLAVEOF命令让其他还活着的节点成为新的Master的Slave节点。
最后推荐一篇文章,我觉得讲解通信的过程讲的很详细:一文读懂Redis的哨兵机制 - 知乎
好东西当然是要一起分享了。
结语
写到这里,Redis的哨兵模式基本是给大家讲解清楚了,不知道你get到了多少?如果还有其他疑问,不放评论区留言和小伙伴们一起讨论吧,最后,不要吝啬你们的赞,动动小手,给博主一个大大的支持吧。