Redis中的集群(九)
集群
消息
集群中的各个节点通过发送和接收消息(message)来进行通信,我们称发送消息的节点为发送者(sender),接收消息
的节点成为接收者,如图所示。节点发送的消息主要有以下五种:
- 1.MEET消息:当发送者接到客户端发送的CLUSTER MEET命令时,发送者会向接收者发送MEET消息,请求接收者加入到发送者当前所处的集群里面
- 2.PING消息:集群里每个节点默认每隔一秒钟就会从已知节点列表中随机选出五个节点,然后对这五个节点中最长时间没有发送过PING消息的节点发送PING消息,以此来检测被选中的节点是否在线。除此之外,如果节点A最后一次收到节点B发送的PONG消息的时间,距离当前时间已经超过了节点A的cluster-node-timeout选项设置时长的一般,那么节点A也会向节点B发送PING消息,这可以防止节点A因为长事件没有随机选中节点B作为PING消息的发送对象而导致对象节点B的信息更新滞后
- 3.PONG消息,当接收者收到发送者发来的MEET消息或者PING消息时,为了向发送者确认这条MEET消息或者PING消息已经到达,接收者会向发送者返回一条PONG消息。另外,一个节点也可以通过向集群广播自己的PONG消息来让集群中的其他节点立即刷新关于这个节点的认识,例如当一次故障转移操作成功执行之后,新的主节点会向集群广播一条PONG消息,以此来让集群中的其他节点立即知道这个节点已经变成了主节点,并且接管了已下线节点负责的槽
- 4.FAIL消息:当一个主节点A判断另一个主节点B已经进入FAIL状态时,节点A会向集群广播一条关于节点B的FAIL消息,所有收到这条消息的节点都会立即将节点B标记为已下线
- 5.PUBLISH消息:当节点接收到一个PUBLISH命令时,节点会执行这个命令,并向集群广播一条PUBLISH消息,所有接收到这条PUBLISH消息的节点都会执行相同的PUBLISH命令

一条消息由消息头(header)和消息正文(data)组成
消息头
节点发送的所有消息都由一个消息头包裹,消息头除了包含消息正文之外,还记录了消息发送者自身的一些信息,因为这些信息也会被消息接收者用到,所以严格来讲,可以认为消息头本身也是消息的一部分。
每个消息头都由一个cluster.h/clusterMsg结构表示clusterMsg.data属性指向联合cluster.h/clusterMsgData,这个联合就是消息的正文:
clusterMsg结构的currentEpoch、sender、myslots等属性记录了发送者自身的节点信息,接收者会根据这些信息在自己的clusterState.nodes字典里找到发送者对应的clusterNode结构,并对结构进行更新
例子
- 举个例子,通过对比接收者为发送者记录的槽指派信息,以及发送者在消息头的myslots属性记录的槽指派信息,接收者可以知道发送者的槽指派信息是否发生了变化,又或者说,通过对比接收者为发送者记录的标识值,以及发送者在消息头的flags属性记录的标识值,接收者可以知道发送者的状态和角色是否发生了变化,例如节点状态由原来的在线变成了下线,或者由主节点变成了从节点等等
clusterMsg结构表示
typedef struct {
// 消息的长度(包括这个消息头的长度和消息正文的长度)
uint32_t totlen;// 消息的类型
uint16_t type;// 消息正文包含的节点信息数量
// 只在发送MEET、PING、PONG这三种Gossip协议信息时使用
uint16_t count;// 发送者所处的纪元
uint64_t currentEpoch;// 如果发送者是一个主节点,那么这里记录的是发送者的配置纪元
// 如果发送者是一个从节点,那么这里记录的是发送者正在复制的主节点的配置纪元
uint64_t configEpoch;// 发送者的名字(id)
char sender[REDIS_CLUSTER_NAMELEN];// 发送者目前的槽指派信息
unsigned char myslots[REDIS_CLUSTER_SLOTS/8];
// 如果发送者是一个从节点,那么这里记录的是发送者正在复制的主节点的名字
// 如果发送者是一个主节点,那么这里记录的是REDIS_NODE_NULL_NAME
char slaveof[REDIS_CLUSTER_NAMELEN];
// 发送者的端口号
uint16_t port;
// 发送者的标识值
uint16_t flags;// 发送者所处集群的状态
unsigned char state;
// 消息的正文(或者说,内容)
unio clusterMsgData data;
}clusterMsg;
clusterMsgData表示
union clusterMsgData {
struct {
// MEET、PING、PONG消息都包含两个clusterMsgDataGossip结构
clusterMsgDataGossip gossip[1];
} ping;// FAIL消息的正文
struct {
clusterMsgDataFail abount;
}fail;// PUBLISH消息的正文
struct {
clusterMsgDataPublish msg;
}publish;// 其他消息正文...
}
MEET、PING、PONG消息的实现
Redis集群中的各个节点通过Gossip协议来交换各自不同节点的状态信息,其中Gossip协议由MEET、PING、PONG三种消息实现,这三种消息的正文都由两个cluster.h/clusterMsgDataGossip结构组成:
union clusterMsgData {
// ...
// MEET、PING和PONG消息的正文
struct {
// 每条MEET、PING、PONG消息都包含两个
// clusterMsgDataGossip结构
clusterMsgDataGossip gossip[1];
}ping
};
因为MEET、PING、PONG三种消息都由相同的消息正文,所以节点通过消息头的type属性来判断一条消息是MEET消息、PING消息和PONG消息。每次发送MEET、PING、PONG消息时,发送者都从自己的已知节点列表中随机选出两个节点(可以是这个主节点或者从节点),并将这两个被选中节点的信息分别保存到两个clusterMsgDataGossip结构里面。
clusterMsgDataGossip结构记录了被选中节点的名字,发送者与被选中节点最后一次发送和接收PING消息和PONG消息的时间戳,被选中节点的IP地址和端口号,以及被选中节点的标识值:
typedef struct {
// 节点的名字
char nodename[REDIS_CLUSTER_NAMELEN];
// 最后一次向该节点发送PING消息的时间戳
uint32_t ping_sent;
// 最后一次从该节点接收到PONG消息的时间戳
uint32_t pong_received;// 节点的IP地址
char ip[16];
// 节点的端口号
uint16_t port;
// 节点的标识值
uint16_t flags;
}clsterMsgDataGossip
当接收者收到MEET、PING、PONG消息时,接收者会访问消息正文中的两个clusterMsgDataGossip结构,并根据自己是否认识clusterMsgDataGossip结构中记录的被选中节点来选择进行哪种操作:
- 1.如果被选中节点不存在于接收者的已知节点列表,那么说明接收者是第一次接触到被选中节点,接收者将根据结构中记录的IP地址和端口号等信息,与被选中节点进行握手.
- 2.如果被选中节点已经存在与接收者的已知节点列表,那么说明接收者之前已经被选中节点进行过接触,接收者将根据clusterMsgDataGossip
结构记录的信息,对被选中节点所对应的clusterNode结构进行更新
例子
- 举个发送PING消息和返回PONG消息的例子,假设在一个包含A、B、C、D、E、F六个节点的集群里:
1.节点A向节点D发送PING消息,并且消息里面包含了节点B和节点C信息,当节点D接收到这条信息,它将更新自己对节点B和节点C的认知
2.之后,节点D将向节点A返回一条PONG消息,并且消息里面包含了节点E和节点F的消息,当节点A接收到这条PONG消息时,它将更新自己对节点E和节点F的认知。

相关文章:
Redis中的集群(九)
集群 消息 集群中的各个节点通过发送和接收消息(message)来进行通信,我们称发送消息的节点为发送者(sender),接收消息 的节点成为接收者,如图所示。节点发送的消息主要有以下五种: 1.MEET消息:当发送者接到客户端发送的CLUSTER MEET命令时,…...
funasr 麦克风实时流语音识别
参考: https://github.com/alibaba-damo-academy/FunASR chunk_size 是用于流式传输延迟的配置。[0,10,5] 表示实时显示的粒度为 1060=600 毫秒,并且预测的向前信息为 560=300 毫秒。每个推理输入为 600 毫秒(采样点为 16000*0.6=960),输出为相应的文本。对于最后一个语音…...
英语学习笔记-音节划分和字母发音对照表
国际音标 音节划分 英语音节以元音为主体构成的发音单位,一般说来元音发音响亮,可以构成音节,辅音发音不响亮,不能单独构成音节 ((m] (n] [I] 例外)。 从单词拼写形式上看,有几个元字组就有几个音节 音节划分规则 长…...
使用odbc链接dm8数据库
一、环境说明 windows11 VMware Workstation 17 Pro ubuntu22.04 docker $ lsb_release -a No LSB modules are available. Distributor ID: Ubuntu Description: Ubuntu 22.04.3 LTS Release: 22.04 Codename: jammy因docker版本的dm8中,没有…...
开源项目one-api的k8s容器化部署(上)-- 制作镜像及部署准备
一、背景 最近需要对开源项目one-api进行k8s容器化部署,主要分以下几个步骤: 制作docker镜像申请mysql和redis数据库docker-compose部署方式k8s部署方式 整个的篇幅比较长,将会分成上下两篇来阐述。 二、制作docker镜像 开源项目one-api…...
面试-数据库基础以及MySql、ClickHost、Redis简介
面试-数据库基础以及MySql、ClickHost、Redis简介 0.数据完整性1.数据库并发控制1.1事物1.2 并发读写错误1.3 锁1.3.1 乐观锁与悲观锁1.3.2 共享锁和排他锁1.3.3 行锁与表锁1.3.4 意向锁 1.4 封锁协议与隔离级别1.5 MVCC1.5.1 概念1.5.2 当前读与快照读1.5.3 MVCC in InnoDB 2.…...
MySQL分库分表的方式有哪些
目录 一、为什么要分库分表 二、什么是分库分表 三、分库分表的几种方式 1.垂直拆分 2. 水平拆分 四、分库分表带来的问题 五、分库分表技术如何选型 一、为什么要分库分表 如果一个网站业务快速发展,那这个网站流量也会增加,数据的压力也会随之而…...
数据结构课程设计选做(一)---数字排序(哈希、排序)
2.1.1 题目内容 2.1.1-A [问题描述] 给定n个整数,请统计出每个整数出现的次数,按出现次数从多到少的顺序输出。 2.1.1-B [基本要求] (1)输入格式: 输入的第一行包含一个整数n,表示给定数字的个数。 第二…...
Linux第90步_异步通知实验
“异步通知”的核心就是信号,由“驱动设备”主动报告给“应用程序”的。 1、添加“EXTI3.c” #include "EXTI3.h" #include <linux/gpio.h> //使能gpio_request(),gpio_free(),gpio_direction_input(), //使能gpio_direction_output(),gpio_get_v…...
elasticdump之python脚本
参考文章目录 elasticdump之shell备份脚本 前言 在企业实际生产环境中,避免不了要对es集群进行迁移、数据备份与恢复,以此来确保数据的可用性及完整性。因此,就涉及到了数据备份与恢复。本章主要以elasticdumppython为主,实现es集群索引备…...
Hystrix应用:如何在Spring Boot中使用Hystrix?
Hystrix应用:如何在Spring Boot中使用Hystrix? 引言 在微服务架构的发展过程中,面对复杂的服务依赖和不可预见的系统故障,如何提升系统的容错能力成为了一个非常急迫且重要的能力。 由 Netflix(网飞)公司…...
js的常用方法
js的常用方法已经使用过的实例 JavaScript有许多基本方法,这些方法可用于执行各种操作,包括字符串操作、数组操作、数学运算等。以下是一些常用的JavaScript基本方法及简单示例: 一、字符串方法 1、toUpperCase():将字符串转换为…...
基于SpringBoot实现的在线拍卖系统
系统开发环境 编程语言:Java数据库:MySQL容器:Tomcat工具:IDEA/Ecilpse、Navicat、Maven 系统实现 管理员功能模块 首页 修改密码 用户管理 商品类型管理 拍卖商品 竞拍公告 轮播图 历史竞拍管理 竞拍订单管理 留言板管理 用户…...
React 组件生命周期对比:Class vs. 函数式
在 React 中,Class 组件和函数式组件的生命周期存在一些差异。通过对 React 中 Class 组件和函数式组件的生命周期进行对比,详细探讨了它们在设计哲学、生命周期管理和开发技巧上的异同。全面了解 React 中两种组件类型的生命周期特点,以及如…...
Ubuntu去除烦人的顶部【活动】按钮
文章目录 一、需求说明二、打开 extensions 网站三、安装 GNOME Shell 插件四、安装本地连接器五、安装 Hide Activities Button 插件六、最终效果七、卸载本地连接器命令参考 本文所使用的 Ubuntu 系统版本是 Ubuntu 22.04 ! 一、需求说明 使用 Ubuntu 的过程中,屏…...
Vue2(十五):replace属性、编程式路由导航、缓存路由组件、路由组件独有钩子、路由守卫、history与hash
一、router-link的replace属性 1、作用:控制路由跳转时操作浏览器历史记录的模式 2、浏览器的历史记录有两种写入方式:分别为push和replace,push是追加历史记录,replace是替换当前记录。路由跳转时候默认为push 3、如何开启repla…...
智慧污水井物联网远程监控案例
智慧污水井物联网远程监控案例 在当今数字化转型的浪潮中,智慧水务已成为城市基础设施建设的重要组成部分。其中,基于物联网技术的智慧污水井远程监控系统以其高效、精准、实时的特性,在提升污水处理效能、保障城市水环境安全、实现精细化管…...
程序员Java.vue,python前端后端爬虫开发资源分享
bat面试资料 bat面试题汇总 提取码:724z 更多资料...
PCL:基于法线微分分割
1.介绍 在三维点云处理中,法线微分分割(Difference of Normals,简称DoN)是一种常用的分割方法,用于将点云中的物体或者场景进行分割成不同的部分或者簇。通过计算点云中每个点的法线向量,以及法线向量的变化率(差异),可以有效地分割出具有明显形状差异的部分,从而实现…...
生产事故:线程管理不善诱发P0故障
背景 处于业务诉求,需要建立一个统一的调度平台,最终是基于 Dolphinscheduler 的 V1.3.6 版本去做二次开发。在平台调研建立时,这个版本是最新的版本 命运之轮开始转动 事故 表象 上班后业务部门反馈工作流阻塞,登录系统发现大…...
使用 SymPy 进行向量和矩阵的高级操作
在科学计算和工程领域,向量和矩阵操作是解决问题的核心技能之一。Python 的 SymPy 库提供了强大的符号计算功能,能够高效地处理向量和矩阵的各种操作。本文将深入探讨如何使用 SymPy 进行向量和矩阵的创建、合并以及维度拓展等操作,并通过具体…...
Spring Cloud Gateway 中自定义验证码接口返回 404 的排查与解决
Spring Cloud Gateway 中自定义验证码接口返回 404 的排查与解决 问题背景 在一个基于 Spring Cloud Gateway WebFlux 构建的微服务项目中,新增了一个本地验证码接口 /code,使用函数式路由(RouterFunction)和 Hutool 的 Circle…...
【笔记】WSL 中 Rust 安装与测试完整记录
#工作记录 WSL 中 Rust 安装与测试完整记录 1. 运行环境 系统:Ubuntu 24.04 LTS (WSL2)架构:x86_64 (GNU/Linux)Rust 版本:rustc 1.87.0 (2025-05-09)Cargo 版本:cargo 1.87.0 (2025-05-06) 2. 安装 Rust 2.1 使用 Rust 官方安…...
无人机侦测与反制技术的进展与应用
国家电网无人机侦测与反制技术的进展与应用 引言 随着无人机(无人驾驶飞行器,UAV)技术的快速发展,其在商业、娱乐和军事领域的广泛应用带来了新的安全挑战。特别是对于关键基础设施如电力系统,无人机的“黑飞”&…...
快刀集(1): 一刀斩断视频片头广告
一刀流:用一个简单脚本,秒杀视频片头广告,还你清爽观影体验。 1. 引子 作为一个爱生活、爱学习、爱收藏高清资源的老码农,平时写代码之余看看电影、补补片,是再正常不过的事。 电影嘛,要沉浸,…...
第7篇:中间件全链路监控与 SQL 性能分析实践
7.1 章节导读 在构建数据库中间件的过程中,可观测性 和 性能分析 是保障系统稳定性与可维护性的核心能力。 特别是在复杂分布式场景中,必须做到: 🔍 追踪每一条 SQL 的生命周期(从入口到数据库执行)&#…...
【LeetCode】3309. 连接二进制表示可形成的最大数值(递归|回溯|位运算)
LeetCode 3309. 连接二进制表示可形成的最大数值(中等) 题目描述解题思路Java代码 题目描述 题目链接:LeetCode 3309. 连接二进制表示可形成的最大数值(中等) 给你一个长度为 3 的整数数组 nums。 现以某种顺序 连接…...
毫米波雷达基础理论(3D+4D)
3D、4D毫米波雷达基础知识及厂商选型 PreView : https://mp.weixin.qq.com/s/bQkju4r6med7I3TBGJI_bQ 1. FMCW毫米波雷达基础知识 主要参考博文: 一文入门汽车毫米波雷达基本原理 :https://mp.weixin.qq.com/s/_EN7A5lKcz2Eh8dLnjE19w 毫米波雷达基础…...
tomcat指定使用的jdk版本
说明 有时候需要对tomcat配置指定的jdk版本号,此时,我们可以通过以下方式进行配置 设置方式 找到tomcat的bin目录中的setclasspath.bat。如果是linux系统则是setclasspath.sh set JAVA_HOMEC:\Program Files\Java\jdk8 set JRE_HOMEC:\Program Files…...
嵌入式学习之系统编程(九)OSI模型、TCP/IP模型、UDP协议网络相关编程(6.3)
目录 一、网络编程--OSI模型 二、网络编程--TCP/IP模型 三、网络接口 四、UDP网络相关编程及主要函数 编辑编辑 UDP的特征 socke函数 bind函数 recvfrom函数(接收函数) sendto函数(发送函数) 五、网络编程之 UDP 用…...
