Java开发 - 深入理解Redis哨兵机制原理

前言

Redis的主从、哨兵模式、集群模式,在前文中都已经有了详细的搭建流程,可谓是手把手教程,也得到了很多朋友的喜欢。由于前文偏向于应用方面,就导致了理论知识的匮乏,我们可能会用了,但却不明所以,所以今天,博主就通过接下里的几篇博客给大家分别讲解Redis哨兵机制的原理和集群模式下的原理。

导读

在开始讲解之前,博主把前面几篇博客的地址放在这里供大家去翻阅:

Java开发 - 让你少走弯路的Redis的主从复制

Java开发 - 让你少走弯路的Redis主从实现单节点哨兵模式

Java开发 - 让你少走弯路的Redis集群搭建

在这三篇Redis内容中,已经从主从到哨兵再到集群给大家一步步做了详细的应用讲解,如果你对Redis的使用还存在一定的问题的话不妨去看看,兴许会有一些新的收获。

多哨兵模式的疑问

在 Redis集群搭建这篇博客的末尾,博主有这么一段话,见下方:

817a633809424f59b95b5add1fe5fddb.png

 一个sentinel哨兵大家会了,但是多个sentinel哨兵怎么让他们彼此之间也能监听到呢?诚如博主所说,多个哨兵和一个哨兵的使用方法是一样的,只需要监听主节点,其他的,哨兵会自动完成。

不信?博主专门搭建了一个多哨兵的Redis,我们来看看。

这是我的Redis和Sentinel配置文件:

3f754e41994a4666bf83eda984309252.png

Redis架构如下:

10bd3fb864a74f7998de7767d0b895d0.png

就是简单的一主二从。

Sentinel的架构如下:

e0150d0465894e309fd5648bc7f4e2b0.png

我们分别启动三个Redis和三个Sentinel:

e5b7b9b8a62b4ae6a5d1b22597863912.png

至于配置,就和我博客里面的一摸一样,大家可以照着自己做,这里是演示多个sentinel的工作情况。

如果你要是自己看了报文,你就会发现细节:

8fa9dc68ff3043dda35d1526d0f7a8d5.png

这个26380的:

a7389efcbac942fe9738ef576740cd4e.png

这是26379的:

57118f66efb345d58d9420402a0162ae.png

唯一配置变的地方还真有一个,就是在sentinel的配置文件中:

sentinel monitor mymaster 127.0.0.1 6379 2

监听的主节点后面的数字变了,一个sentinel的时候写1,三个sentinel的时候要过半的sentinel认为主节点挂掉才能故障转移和切换,三个,那过半就写2了,如果你有更多sentinel,这个数字也要改变。当然,你写1也行,但可能出现误判的情况。

测试关闭主节点:

f399cd0515424e6e960a9ae49b4a9ef4.png

已关闭,此时看从节点:

78cda6e7b3a74a13b68ce04c79a11513.png

出现了短暂的连接被拒绝的情况,此时我们发现sentinel没有任何变化,大概也就是几秒钟的样子,变化产生了:

7aa9d6ba6a324e89a372ddce115112f5.png

此时去看其他的sentinel节点,会发现有明显的选举过程:

9b4270e2102549b2b443b98a9c365add.png

此时如果把sentinel6379下线掉之后,会发生什么?我们试试;

d8237dad61574174b200506ad93ffd04.png

大概在几秒后,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的判断。我们可以认为他们是通过主节点达到数据共享的。

9cb8c0a3f08d407abfdac679ac30cb8f.png

我们暂时就理解到这里,不再做更多深层的源码方面的理解。

但当博主打开了sentinel26379的配置文件,偶然在最末位发现了这几段自动生成的配置,似乎打开了新世界的大门:

bfed9fd640834aa783972fd7ae7250f4.png

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到了多少?如果还有其他疑问,不放评论区留言和小伙伴们一起讨论吧,最后,不要吝啬你们的赞,动动小手,给博主一个大大的支持吧。

猜你喜欢

转载自blog.csdn.net/CodingFire/article/details/131609743