Redis集群模式之Redis Cluster(2)

        上篇文章我们讲解了Redis Cluster中的主要模块和两种重定向方式,这篇文章我们来讲解一下Redis Cluster的状态监测和维护。

Redis Cluster状态监测及维护

        要讲解Redis Cluster中节点的状态如何维护,我们要先知道Redis Cluster中的节点有哪些状态,gossip协议是什么以及具体的通讯(心跳)机制。

节点状态

        Redis Cluster中的每个节点都维护着一份在自己看来当前整个集群的状态,主要包括:

        (1)当前集群的状态;

        (2)集群中各节点所负责的Slots信息,及其migrate状态;

        (3)集群中各节点的Master-Slave状态;

        (4)集群中各节点的存活状态及不可达投票。

        当集群的状态发生变化时,比如新节点的加入、Slot迁移、节点宕机、新Master的出现等,我们希望这些变化尽快的被发现,传播到整个集群的所有节点并达成一致。节点之间相互的心跳(PING、PONG、MEET)及其携带的数据是集群状态传播最主要的途径。

gossip协议

        gossip协议又称为epidemic协议,是基于流行病传播方式的节点或进程之间信息交换的协议。在分布式系统中被广泛使用,比如我们可以使用gossip协议来确保网络中所有节点的数据一样。

        gossip协议已经是P2P网络中比较成熟的协议了。gossip协议的最大好处是,即使集群节点的数量增加,每个节点的负载也不会增加很多,几乎是恒定的。这就允许Consul管理的集群规模能横向扩展到数千个节点。

        Redis集群是去中心化的,彼此之间状态同步靠gossip协议通信,集群的消息有以下几种类型:

        (1)Meet:通过cluster meet ip port命令,已有集群的节点会向新的节点发送邀请,加入现有集群。

        (2)Ping:节点每秒会向集群中其他节点发送Ping消息,消息中带有自己已知的两个节点的地址、槽、状态信息、最后一次通信时间等。

        (3)Pong:节点收到Ping消息后会回复Pong消息,消息中同样带有自己已知的两个节点消息。

        (4)Fail:节点Ping不通某节点后,会向集群所有节点广播该节点挂掉的消息。其他节点收到消息后标记为已下线。        

        集群中的每个节点都会定期地向集群中的其他节点发送PING消息,以此交换各个节点状态信息,检测各个节点的状态:在线状态、疑似下线状态PFAIL、已下线状态FAIL。

        当主节点A通过消息得知主节点B认为主节点D进入疑似下线状态时,主节点A会在自己的clusterState.nodes字典中找到主节点D所对应的clusterNode结构,并将主节点B的下线报告添加到clusterNode结构的fail_reports链表中,并后续关于节点D疑似下线的状态通过gossip协议通知其他节点。

        如果集群中,半数以上的主节点都将主节点D报告为下线状态,那么主节点D就被标记为已下线状态,将主节点D标记为已下线的节点会向集群广播主节点D的Fail消息,所有收到Fail消息的节点都会立即更新nodes里面主节点D的状态,标记为已下线。

        将node标记为FAIL需要满足一下两个条件:①有半数以上的主节点将node标记为PFAIL状态。②当前节点也将node标记为PFAIL状态。

通讯状态和维护

        什么时候进行心跳?

        Redis节点会记录其向每一个节点上一次发出ping和收到pong的时间,心跳发送时机与这两个值有关。通过下面的方式既能保证及时更新集群状态,又不至于使心跳次数过多:

        (1)每次Cron向所有未建立链接的节点发送ping或meet;

        (2)每1秒从所有已知节点中随机选取5个,向其中上次收到的pong最久远的一个发送ping。

        (3)每次Cron向收到pong超过timeout/2的节点发送pong;

        (4)收到ping或者meet,立即回复pong。

        发送哪些心跳数据?

        (1)Header:发送者自己的信息,包括所负责的slots信息、主从信息、ip port信息和状态信息。

        (2)gossip:发送者所了解的部分其他节点的信息,包括ping_sent,pong_received、ip,port信息、状态信息(比如发送者认为该节点已经不可达,会在状态信息中标记其为PFAIL或FAIL)。

        如何处理心跳数据?

        (1)新节点的加入。发送meet包加入集群,从pong包中的gossip得到未知的其他节点。通过循环上述过程,直到最终加入集群。

        (2)slots信息。判断发送者声明的slots信息,跟本地记录的是否有不同。如果不同,并且发送者epoch较大,更新本地记录;如果不同,并且发送者epoch比较小,发送update信息通知发送者。

        (3)Master slave信息。发现发送者的master、slave信息变化,更新本地状态。

        (4)节点FAIL探测(故障发现)。超过超时时间仍然没有收到pong包的节点会被当前节点标记为PFAIL;PFAIL标记会随着gossip传播;每次收到心跳包会检测其中对其他节点的PFAIL标记,当做对该节点FAIL的投票维护在本机;对某个节点的PFAIL标记达到大多数时,将其变为FAIL标记并广播FAIL消息。

        gossip的存在使得集群状态的改变可以更快的达到整个集群。每个心跳包中会包含多个gossip包,那么多少个才是合适的呢,Redis的选择是N/10,其中N是节点数,这样可以保证在PFAIL投票的过期时间内,节点可以收到80%机器关于失败节点的gossip,从而使其顺利进入Fail状态。

        如何将信息广播给其它节点?

        当需要发布一些非常重要需要立即送达的消息时,上述心跳+gossip的方式就显得捉襟见肘了,这时就需要向所有集群内的机器广播信息,使用广播发的场景:

        节点的Fail信息:当发现某一节点不可达时,探测节点会将其标记为PFAIL状态,并通过心跳传播出去。当某一节点发现这个节点的PFAIL超过半数时修改其为FAIL并发起广播。

        Failover Request信息:slave尝试发起FailOver时广播其要求投票的信息。

        新Master信息:Failover成功的节点向整个集群广播自己的信息。

故障恢复

        当slave发现自己的master变为FAIL状态时,便尝试进行Failover,以期成为新的Master。由于挂掉的Master可能会有多个Slave。Failover的过程需要经过类Raft协议的过程在整个集群内达到一致,具体的过程如下:

        (1)Slave发现自己的Master变为FAIL;

        (2)将自己记录的集群currentepoch+1,并广播Failover Request信息;

        (3)其他节点收到该消息,只有Master响应,判断请求者的合法性,并发送FAILOVER_AUTH_ACK,对每一个epoch只发送一次ack;

        (4)尝试Failover的Slave收集FAILOVER_AUTH_ACK;

        (5)超过半数后变为新Master;

        (6)广播Pong通知其他集群节点。

        这篇文章我们主要讲解了Redis Cluster的状态监测和维护,大家有什么问题或勘误可以在评论区留言,笔者看到都会回复的。

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

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

相关文章

Step-Audio-AQAA 解读:迈向「纯语音」交互的端到端 LALM 新里程

引言:AI 从听到说 大型音频语言模型(Large Audio-Language Models, LALMs)正在彻底改变我们与机器交互的方式。我们不再满足于简单的文本问答,而是期望 AI 能够像人类一样,通过自然的语音进行交流,理解我们的意图,并以富有表现力的声音回应。然而,构建一个能够直接从语…

基于边缘计算的丝杆状态实时监测系统设计?

基于边缘计算的丝杆状态实时监测系统设计,可从系统架构、各层功能设计、关键技术应用等方面入手,以下为详细介绍: 系统架构设计 基于边缘计算的丝杆状态实时监测系统通常由感知层、边缘层和云端三部分组成。感知层负责数据采集,…

LeetCode 每日一题 2025/6/9-2025/6/15

记录了初步解题思路 以及本地实现代码;并不一定为最优 也希望大家能一起探讨 一起进步 目录 6/9 440. 字典序的第K小数字6/10 3442. 奇偶频次间的最大差值 I6/11 3445. 奇偶频次间的最大差值 II6/12 3423. 循环数组中相邻元素的最大差值6/13 2616. 最小化数对的最大…

PyTorch张量操作中dim参数的核心原理与应用技巧:

今天在搭建神经网络模型中重写forward函数时,对输出结果在最后一个维度上应用 Softmax 函数,将输出转化为概率分布。但对于dim的概念不是很熟悉,经过查阅后整理了一下内容。 PyTorch张量操作精解:深入理解dim参数的维度规则与实践…

Day 31

1. 规范的文件命名 核心原则: 清晰明确:文件名应准确描述内容(如data_preprocessing.py) 风格统一: 推荐小写下划线(Python惯例,如model_training.py) 或使用驼峰式&#xff08…

学习Oracle------认识VARCHAR2

学习Oracle------认识VARCHAR2 VARCHAR2 是 Oracle 数据库中专门用于存储可变长度字符串的数据类型,它是 Oracle 对标准 SQL 数据类型 VARCHAR 的增强和替代。以下是全面解析: 核心概念 名字含义: VAR Variable(可变&#xff09…

记录jackson解析出错

Jackson 属性名大小写 Bug 记录 问题描述 在前后端交互过程中,前端传递的 JSON 字段名为驼峰风格(如 qTitle),后端 Java 实体类字段名也为驼峰(如 private String qTitle;)。 但在反序列化时,…

泰国数码电商系统定制|3C产品详情泰语化+售后管理,适配泰国数码零售

随着全球数字化的加速,电商行业正在迅速发展,尤其是以泰国为代表的东南亚市场。泰国不仅是一个拥有庞大消费者群体的市场,而且其日益增长的互联网使用率和手机普及率使得数码产品的销售潜力巨大。在这样的大背景下,针对泰国市场的…

59、定制化原理-SpringBoot定制化组件的几种方式

59、定制化原理-SpringBoot定制化组件的几种方式 在Spring Boot中,定制化组件的方式多样,以下是几种常见的方法及其原理: #### 修改配置文件 通过修改application.properties或application.yml文件,利用ConfigurationProperties注…

机器学习--分类

阳性(Positive)和阴性(Negative) 阳性(Positive) 正类:通常指的是我们关注的类别或事件;阴性(Negative) 负类: 指的是与阳性相反的类别或事件。…

三星MZQL2960HCJR-00BAL高性能固态硬盘控制器SSD云计算和高端存储专用 电子元器件解析

MZQL2960HCJR-00BAL 电子元器件解析 1. 基本类型与功能 MZQL2960HCJR-00BAL 是 三星(Samsung) 推出的一款 企业级NVMe SSD主控芯片,属于 高性能固态硬盘控制器,专为 数据中心、云计算和高端存储 设计。 关键特性: 接…

Blender——建构、粒子、灯光、动画

Blender是一款开源的三维建模和动画软件,可用于创建3D模型、动画、渲染图像和视频,还支持雕刻、纹理绘制、粒子系统等功能。 建构篇: 基本操作: 视角的控制: 控制观察视角: 鼠标中键 平移视图: Shift鼠标中键 缩放视…

节日快乐啊

<section data-role"paragraph" class"_135editor"> <p> <br/> </p> </section> <p> 玛哈特2025中国国际金属成形展览会邀请函 </p><style>* { margin: 0; …

PHP和Node.js哪个更爽?

先说结论&#xff0c;rust完胜。 php&#xff1a;laravel&#xff0c;swoole&#xff0c;webman&#xff0c;最开始在苏宁的时候写了几年php&#xff0c;当时觉得php真的是世界上最好的语言&#xff0c;因为当初活在舒适圈里&#xff0c;不愿意跳出来&#xff0c;就好比当初活在…

LeetCode - 387. 字符串中的第一个唯一字符

题目 387. 字符串中的第一个唯一字符 - 力扣&#xff08;LeetCode&#xff09; 思路 用哈希表统计每个字符出现的次数 创建一个 unordered_map<char, int>&#xff0c;遍历字符串&#xff0c;把每个字符出现的次数存进去。 再遍历字符串&#xff0c;找到第一个只出现…

python从环境变量和配置文件中获取配置参数

前言 从环境变量和配置文件中获取配置参数&#xff0c;相关库&#xff1a; python-dotenv&#xff1a;第三方库&#xff0c;需要使用pip安装configparser&#xff1a;标准库 代码 test.ini [mysql] host "192.168.0.10" port 3306 user "root" pas…

HarmonyOS5 运动健康app(一):健康饮食(附代码)

一、核心数据模型设计 代码通过两个接口构建了饮食管理的基础数据结构&#xff1a; interface footItem {name: string; // 营养名称&#xff08;蛋白质/碳水/脂肪&#xff09;weight: number; // 重量&#xff08;克&#xff09; }interface DietItem {name: string; // 食物…

MQ选型及RocketMQ架构总览

一、什么是MQ MQ&#xff08;MessageQueue&#xff09; Message(消息)&#xff1a;消息是在不同进程之间传递的数据&#xff0c;这些进程可以在同一台机器上&#xff0c;也可以在不同的机器上。 Queue&#xff08;队列&#xff09;&#xff1a;队列原意是指一种具有FIFO&#…

python与java的区别

java老程序员来学习python了&#xff0c;记录一下两种类型语言的区别&#xff1a; Python与Java变量类型对比 python里面定义变量不需要指定变量的数据类型&#xff0c;并且是可以修改成其他类型java里面定义变量要指定变量的数据类型&#xff0c;指定以后不可以修改成其他数据…

固件签名技术深度解析:HSM模块如何守护设备安全,CAS系统如何赋能产业升级

引言&#xff1a;数字时代的固件安全危机 在万物互联的今天&#xff0c;全球设备固件安全事件频发&#xff1a;某汽车品牌因固件漏洞导致百万车辆被远程控制&#xff0c;某医疗设备厂商因固件篡改引发数据泄露&#xff0c;某工业控制系统因非法固件升级造成生产线瘫痪……这些…