当前位置: 首页 > news >正文

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命令时&#xff0c…...

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步_异步通知实验

“异步通知”的核心就是信号&#xff0c;由“驱动设备”主动报告给“应用程序”的。 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集群进行迁移、数据备份与恢复&#xff0c;以此来确保数据的可用性及完整性。因此&#xff0c;就涉及到了数据备份与恢复。本章主要以elasticdumppython为主&#xff0c;实现es集群索引备…...

Hystrix应用:如何在Spring Boot中使用Hystrix?

Hystrix应用&#xff1a;如何在Spring Boot中使用Hystrix&#xff1f; 引言 在微服务架构的发展过程中&#xff0c;面对复杂的服务依赖和不可预见的系统故障&#xff0c;如何提升系统的容错能力成为了一个非常急迫且重要的能力。 由 Netflix&#xff08;网飞&#xff09;公司…...

js的常用方法

js的常用方法已经使用过的实例 JavaScript有许多基本方法&#xff0c;这些方法可用于执行各种操作&#xff0c;包括字符串操作、数组操作、数学运算等。以下是一些常用的JavaScript基本方法及简单示例&#xff1a; 一、字符串方法 1、toUpperCase()&#xff1a;将字符串转换为…...

基于SpringBoot实现的在线拍卖系统

系统开发环境 编程语言&#xff1a;Java数据库&#xff1a;MySQL容器&#xff1a;Tomcat工具&#xff1a;IDEA/Ecilpse、Navicat、Maven 系统实现 管理员功能模块 首页 修改密码 用户管理 商品类型管理 拍卖商品 竞拍公告 轮播图 历史竞拍管理 竞拍订单管理 留言板管理 用户…...

React 组件生命周期对比:Class vs. 函数式

在 React 中&#xff0c;Class 组件和函数式组件的生命周期存在一些差异。通过对 React 中 Class 组件和函数式组件的生命周期进行对比&#xff0c;详细探讨了它们在设计哲学、生命周期管理和开发技巧上的异同。全面了解 React 中两种组件类型的生命周期特点&#xff0c;以及如…...

Ubuntu去除烦人的顶部【活动】按钮

文章目录 一、需求说明二、打开 extensions 网站三、安装 GNOME Shell 插件四、安装本地连接器五、安装 Hide Activities Button 插件六、最终效果七、卸载本地连接器命令参考 本文所使用的 Ubuntu 系统版本是 Ubuntu 22.04 ! 一、需求说明 使用 Ubuntu 的过程中&#xff0c;屏…...

Vue2(十五):replace属性、编程式路由导航、缓存路由组件、路由组件独有钩子、路由守卫、history与hash

一、router-link的replace属性 1、作用&#xff1a;控制路由跳转时操作浏览器历史记录的模式 2、浏览器的历史记录有两种写入方式&#xff1a;分别为push和replace&#xff0c;push是追加历史记录&#xff0c;replace是替换当前记录。路由跳转时候默认为push 3、如何开启repla…...

智慧污水井物联网远程监控案例

智慧污水井物联网远程监控案例 在当今数字化转型的浪潮中&#xff0c;智慧水务已成为城市基础设施建设的重要组成部分。其中&#xff0c;基于物联网技术的智慧污水井远程监控系统以其高效、精准、实时的特性&#xff0c;在提升污水处理效能、保障城市水环境安全、实现精细化管…...

程序员Java.vue,python前端后端爬虫开发资源分享

bat面试资料 bat面试题汇总 提取码&#xff1a;724z 更多资料...

PCL:基于法线微分分割

1.介绍 在三维点云处理中,法线微分分割(Difference of Normals,简称DoN)是一种常用的分割方法,用于将点云中的物体或者场景进行分割成不同的部分或者簇。通过计算点云中每个点的法线向量,以及法线向量的变化率(差异),可以有效地分割出具有明显形状差异的部分,从而实现…...

生产事故:线程管理不善诱发P0故障

背景 处于业务诉求&#xff0c;需要建立一个统一的调度平台&#xff0c;最终是基于 Dolphinscheduler 的 V1.3.6 版本去做二次开发。在平台调研建立时&#xff0c;这个版本是最新的版本 命运之轮开始转动 事故 表象 上班后业务部门反馈工作流阻塞&#xff0c;登录系统发现大…...

基于算法竞赛的c++编程(28)结构体的进阶应用

结构体的嵌套与复杂数据组织 在C中&#xff0c;结构体可以嵌套使用&#xff0c;形成更复杂的数据结构。例如&#xff0c;可以通过嵌套结构体描述多层级数据关系&#xff1a; struct Address {string city;string street;int zipCode; };struct Employee {string name;int id;…...

Linux简单的操作

ls ls 查看当前目录 ll 查看详细内容 ls -a 查看所有的内容 ls --help 查看方法文档 pwd pwd 查看当前路径 cd cd 转路径 cd .. 转上一级路径 cd 名 转换路径 …...

电脑插入多块移动硬盘后经常出现卡顿和蓝屏

当电脑在插入多块移动硬盘后频繁出现卡顿和蓝屏问题时&#xff0c;可能涉及硬件资源冲突、驱动兼容性、供电不足或系统设置等多方面原因。以下是逐步排查和解决方案&#xff1a; 1. 检查电源供电问题 问题原因&#xff1a;多块移动硬盘同时运行可能导致USB接口供电不足&#x…...

鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个生活电费的缴纳和查询小程序

一、项目初始化与配置 1. 创建项目 ohpm init harmony/utility-payment-app 2. 配置权限 // module.json5 {"requestPermissions": [{"name": "ohos.permission.INTERNET"},{"name": "ohos.permission.GET_NETWORK_INFO"…...

Rust 异步编程

Rust 异步编程 引言 Rust 是一种系统编程语言,以其高性能、安全性以及零成本抽象而著称。在多核处理器成为主流的今天,异步编程成为了一种提高应用性能、优化资源利用的有效手段。本文将深入探讨 Rust 异步编程的核心概念、常用库以及最佳实践。 异步编程基础 什么是异步…...

NLP学习路线图(二十三):长短期记忆网络(LSTM)

在自然语言处理(NLP)领域,我们时刻面临着处理序列数据的核心挑战。无论是理解句子的结构、分析文本的情感,还是实现语言的翻译,都需要模型能够捕捉词语之间依时序产生的复杂依赖关系。传统的神经网络结构在处理这种序列依赖时显得力不从心,而循环神经网络(RNN) 曾被视为…...

c#开发AI模型对话

AI模型 前面已经介绍了一般AI模型本地部署&#xff0c;直接调用现成的模型数据。这里主要讲述讲接口集成到我们自己的程序中使用方式。 微软提供了ML.NET来开发和使用AI模型&#xff0c;但是目前国内可能使用不多&#xff0c;至少实践例子很少看见。开发训练模型就不介绍了&am…...

成都鼎讯硬核科技!雷达目标与干扰模拟器,以卓越性能制胜电磁频谱战

在现代战争中&#xff0c;电磁频谱已成为继陆、海、空、天之后的 “第五维战场”&#xff0c;雷达作为电磁频谱领域的关键装备&#xff0c;其干扰与抗干扰能力的较量&#xff0c;直接影响着战争的胜负走向。由成都鼎讯科技匠心打造的雷达目标与干扰模拟器&#xff0c;凭借数字射…...

docker 部署发现spring.profiles.active 问题

报错&#xff1a; org.springframework.boot.context.config.InvalidConfigDataPropertyException: Property spring.profiles.active imported from location class path resource [application-test.yml] is invalid in a profile specific resource [origin: class path re…...

在QWebEngineView上实现鼠标、触摸等事件捕获的解决方案

这个问题我看其他博主也写了&#xff0c;要么要会员、要么写的乱七八糟。这里我整理一下&#xff0c;把问题说清楚并且给出代码&#xff0c;拿去用就行&#xff0c;照着葫芦画瓢。 问题 在继承QWebEngineView后&#xff0c;重写mousePressEvent或event函数无法捕获鼠标按下事…...