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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/28503.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

自定义实现list及其功能

#pragma once #include <iostream> #include <assert.h> using namespace std;namespace test {//******************************设置结点******************************template<class T>struct list_node{T _data;list_node<T>* _next;list_node&l…

ES6 Generator和Promise

目录 Generator 如何创建Generator函数 ? 模拟发起异步请求 Promise 实例化 实例方法 工厂函数 静态方法 Promise.all([p1,p2,....]) Promise.race([p1,p2,....]) Promise.any([p1,p2,....]) Promise.allSettled([p1,p2,....]) Generator Generator是ES6提供的一种…

云计算与大数据——MPI集群配置

什么是MPI集群&#xff1f; MPI&#xff08;消息传递接口&#xff09;是一种用于编写并行程序的标准&#xff0c;它允许在多个计算节点上进行通信和协作。MPI集群配置是指在一个或多个计算节点上设置MPI环境以实现并行计算。 MPI集群配置的步骤&#xff1a; 硬件选型&#x…

C++--day3(内联函数、结构体、类、封装、this、构造函数、析构函数)

#include <iostream>using namespace std;class My_stack { private:int *ptr; //指向堆区空间int top; //记录栈顶元素int size; public://有参构造My_stack(int size):ptr(new int[size]),top(-1){this->sizesize;cout<<"My_stack::有参构造&…

Django MultiValueDictKeyError 表单数据用request.POST 非表单数据用request.body

表单数据&#xff1a;Content-Type(请求头)为application/x-www-form-urlencoded的数据。 用request.POST获取 a request.POST.get(a) a request.POST[a] alist request.POST.getlist(a) 非表单数据&#xff1a;Content-Type(请求头)为非application/x-www-form-urlenco…

2023年郑州/杭州/深圳CSPM-3中级国标项目管理认证招生

CSPM-3中级项目管理专业人员认证&#xff0c;是中国标准化协会&#xff08;全国项目管理标准化技术委员会秘书处&#xff09;&#xff0c;面向社会开展项目管理专业人员能力的等级证书。旨在构建多层次从业人员培养培训体系&#xff0c;建立健全人才职业能力评价和激励机制的要…

【动态内存错误详解和C的内存分区】

常见的动态内存错误 1.动态内存错误2.经典案例分析2.1案例一2.1.1**问题分析**2.1.2**修改错误** 2.2案例二2.2.1 原因分析2.2.2 解决问题 c/c内存分布1.2 内存分区简介1.2.1 栈区(stack)1.2.2 堆区(heap)1.2.3 全局(静态)区1.2.4 常量区1.2.5 代码区 1.动态内存错误 &#xf…

Argo CD 入门扫盲使用

目录 一、什么是 argo cd 二、为什么使用 argo cd 三、argo cd 架构图 四、Argo CD 使用 1、安装 Argo CD 2、安装 Argo CD CLI 3、发布 Argo CD 服务 4、获取 Argo CD 密码 5、准备 Git 仓库 6、创建 Argo CD App 7、版本升级 8、版本回滚 一、什么是 argo cd A…

STM32学习笔记(十三)丨USART通用同步/异步收发器(串口外设的基本使用丨串口发送数据、串口发送+接收数据)

本篇文章包含的内容 一、STM32的USART外设1.1 STM32的USAER外设简介1.2 USART外设的结构和工作原理1.3 串口通信数据帧1.4 起始位侦测和USART的噪声判断机制1.5 波特率发生器 二、串口发送和接收数据包2.1 HEX数据包2.2 文本数据包2.3 固定包长HEX数据包接收2.4 可变包长文本数…

简单认识MySQL数据库日志和数据的备份恢复

文章目录 Mysql 备份与还原一、数据备份的重要性二、数据库备份类型1 、物理备份2 、逻辑备份 三、常见的备份方法1、 物理冷备2、 专用备份工具 mysqldump 或 mysqlhotcopy3、 启用二进制日志进行增量备份3.4 第三方工具备份 四、MySQL完全备份1、简介2、优点&#xff1a;3、缺…

SAP ABAP 报表程序实现下载文件及上传 Excel 并解析

步骤1&#xff1a; 事务代码 SMW0 选择二进制数据选项点击上方按钮。 点击新建按钮输入名称和描述&#xff0c;上传模版文件。 案例传入 EXCEL 如下&#xff1a; 创建好资源库对象结果如下。 步骤2&#xff1a;报表效果展示 点击按钮选择上传的文件。 解析 Excel 文件结果…

visual studio配置调用c++ dll opencv为例

1&#xff0c;配置VC目录&#xff0c;包含目录和库目录。 2&#xff0c;链接器->输入->包含目录 3&#xff0c;生成目录下包含对应的dll文件 4&#xff0c;需注意对应的Debug&#xff0c;Release及X86&#xff0c;X64选项