Redis 7.x 系列【27】集群原理之通信机制

news2024/11/13 9:28:04

有道无术,术尚可求,有术无道,止于术。

本系列Redis 版本 7.2.5

源码地址:https://gitee.com/pearl-organization/study-redis-demo

文章目录

    • 1. 概述
    • 2 节点和节点
      • 2.1 集群拓扑
      • 2.2 集群总线协议
      • 2.3 流言协议
      • 2.4 心跳机制
      • 2.5 节点握手
    • 3. 客户端和节点
      • 3.1 RESP 协议
      • 3.2 重定向
        • 3.2.1 MOVED
        • 3.2.2 ASK
        • 3.2.3 客户端重定向处理

1. 概述

官方文档

Redis 集群中,节点负责存储数据,并管理集群的状态,包括将键映射到正确的节点。集群节点还能够自动发现其他节点,检测非工作节点,并在需要时提升副本节点为主节点,以便在发生故障时继续运行。

节点和节点之间,节点和客户端之间,都需要高效安全的通信机制,确保整个集群能如期正常运行。

2 节点和节点

所有集群节点之间都是互相连接的,并使用以下协议进行通信:

  • 集群总线协议:节点之间的连接协议
  • 流言协议(‌Gossip Protocol)‌:传播集群信息,以便发现新节点、发送 Ping 数据包
  • 发布/订阅(Pub/Sub):

2.1 集群拓扑

Redis 集群是一个网状结构,其中每个节点通过 TCP 连接与其他每个节点连接,类似于网络中的网状拓扑结构:

在这里插入图片描述

在一个包含 N 个节点的集群中,每个节点有 N-1 个出站连接和 N-1 个入站连接。这些 TCP 连接始终保持活动状态,不是按需创建的。当一个节点在集群总线上期待收到对 Pong 回复时,在等待足够长时间标记节点为不可达之前,会尝试通过从头重新连接来刷新与节点的连接。

网状拓扑结构具有较高的可靠性,但其结构复杂,实现起来费用较高,不易管理和维护。但是 Redis 节点在正常情况下使用 Gossip 协议和配置更新机制,以避免在节点之间交换过多的消息,因此交换的消息数量不会呈指数增长。

2.2 集群总线协议

节点之间的通信完全通过集群总线集群总线协议进行,集群总线协议是一种二进制协议,仅用于内部集群通信,目前没有相关说明,需要在源码中了解。

该协议需要使用集群总线端口进行连接。每个 Redis 集群节点除了监听 6379 运行端口外,还会开放一个额外的 TCP 端口,用于接收来自其他 Redis 集群节点的连接,该端口的计算方式是将运行端口号加上 10000

例如,如果一个 Redis 节点在 6379 端口上监听客户端连接,并且在 redis.conf 中未添加 cluster-port 参数,那么集群总线端口 16379 将会被打开。

可以通过配置文件中的 cluster-port 参数指定集群总线端口:

cluster-port 20000

在安装集群时,需要注意节点默认使用 6379、16379 两个端口

2.3 流言协议

Gossip Protocol(流言协议)是一种高效的分布式信息交换协议,通过模拟流行病传播的方式,实现了节点间信息的快速传播和同步。其去中心化、可扩展性和容错性强的特点,广泛应用于多个分布式系统。

Redis 集群中的节点,会周期性地随机选择一些节点,通过 Ping 将当前节点的信息传递过去。收到信息的节点,也会使用同样的方式传播自己的节点信息。这个过程会持续进行,直到信息被传播到集群中的每一个节点,每个节点都会保存所有其他节点的信息。

2.4 心跳机制

Redis Cluster 会通过心跳检测迅速感知到节点故障,并且在节点故障时自动进行恢复,以确保数据在集群中的可用性。

Redis 集群节点不断地交换 PingPong 数据包,用于检测其他节点的存活状态。这两种数据包总称为心跳数据包,它们具有相同的结构,并且都携带重要的配置信息。

集群节点发送心跳的几种触发方式:

  • 每秒钟向几个随机节点发送 Ping
  • 尝试重新建立与其他节点的 TCP 连接,以确保节点不会因为当前的 TCP 连接问题而被认为是不可达的
  • 向在 NODE_TIMEOUT 时间内没有发送过 Ping 的节点进行发送

心跳数据包 包含了一些通用的内容信息:

  • 节点 ID : 节点创建时分配的全局唯一标识
  • 当前时期(currentEpoch)和配置时期(configEpoch): 发送节点的当前时期和配置时期字段,用于解决配置冲突和故障转移
  • 节点标识: 标识节点是从节点、主节点或其他节点。
  • 哈希槽位图: 发送节点服务的哈希槽位图,或者如果节点是副本,则为其主节点服务的槽位图。
  • 发送者 TCP 数据端口: Redis 用于接受客户端命令的基本端口(6379)。
  • 集群总线端口: Redis 节点间通信使用的端口。
  • 发送者视角下的集群状态: 表示发送节点对集群状态的视角,可以是“down”或“ok”。

新加如节点时,心跳数据包 还包含一些 Gossip 信息:

  • 新节点 ID
  • 新节点的 IP 地址和端口。
  • 新节点标识。

2.5 节点握手

集群节点之间,始终通过集群总线端口保持连接,新节点加入 Redis Cluster 时,需要与集群中的其他节点进行握手,以获取集群的拓扑信息和状态。节点之间会交换握手消息,确认自身角色(主节点、从节点或未分配节点)和负责的槽分配情况。

节点握手的整个流程如下:

  • 任意主节点(例如 A )上执行 CLUSTER MEET 命令,新节点的 IP 地址(例如 X )和端口号作为参数。
  • AX 进行握手操作,以确认彼此的存在和状态。
  • 其他节点通过 Gossip 发现 X 节点,并完成握手
  • 随着时间的推移,集群中的所有节点都会通过 Gossip 协议知道新节点的存在,并将其纳入集群的元数据中。

Redis Cluster 网状拓扑中加入节点,集群能够自动发现其他节点,最终会自动形成一个完整的链路。这种机制使集群更加健壮,并确保了集群的灵活性和可扩展性。

3. 客户端和节点

3.1 RESP 协议

官方文档

Redis 客户端和服务端之间,通过 RESPRedis Serialization Protocol )协议进行通信,它是一个简单的二进制安全协议。Redis 1.2 引入了 RESP 协议的第一个版本。客户端通过创建到服务器端口的 TCP 连接(默认端口为 6379)连接到 Redis 服务端。

RESP 具有以下优点:

  • 易于实现:协议的设计简洁明了,便于开发者实现。
  • 快速解析:协议格式高效,可以迅速被解析,减少通信延迟。
  • 人类可读:尽管主要用于机器通信,但协议格式也便于人类阅读和理解。

RESP 能够序列化不同的数据类型,包括整数、字符串和数组,并且还具有一个专门用于错误的类型。客户端向 Redis 服务器发送请求时,请求以字符串数组的形式发送,数组的内容包括要执行的命令及其参数。服务器的回复类型取决于具体的命令。

RESP 是二进制安全的,并使用前缀长度来传输大量数据,因此它不需要处理从一个进程传输到另一个进程的大量数据。这种设计使得数据传输更加高效和安全。

RESP仅用于客户端与服务器之间的通信,集群使用不同的二进制协议在节点之间交换消息

3.2 重定向

由于集群节点不能代理请求,因此客户端可能会使用重定向错误( -MOVED-ASK )被重定向到其他节点。

理论上,客户端可以自由地向集群中的所有节点发送请求,并在需要时进行重定向,因此客户端不需要持有集群的状态。但是,缓存键和节点之间映射的客户端可以显著提高性能。

3.2.1 MOVED

集群节点会自动分配哈希槽,节点内部也会维护其他所有节点和哈希槽的映射关系,例如,以下三个主节点:
在这里插入图片描述
Redis 客户端可以随意的向集群中的任意一个节点发送查询命令,例如,在 192.168.56.101:6379 节点上执行插入、查询操作,当前 key 的哈希槽编号为 1180

[root@localhost ~]# redis-cli -a cluster123456 -p 6379
127.0.0.1:6379> set aa bb
127.0.0.1:6379> cluster keyslot aa
(integer) 1180
127.0.0.1:6379> get aa 
bb 

如果在 192.168.56.103:6379 节点上执行查询操作,由于该节点的哈希槽为 5461 - 10922 ,节点检查内部映射表时,发现哈希槽编号为 1180key 不属于该节点管理,会向客户端回复一个 MOVED 错误:

127.0.0.1:6379> get aa 
(error) MOVED 1180 192.168.56.101:6379

MOVED 错误中,包含了 key 的哈希槽编号,以及能够处理该查询的集群节点,客户端需要将查询重新发送到指定的节点。

一般客户端,会自动进行重定向,而且不会单独去请求某一个节点,而是维护了所有节点,并在内部维护了一个哈希槽到节点的映射,对于开发者来说,MOVED 重定向是无感知的。

注意:这里需要使用 redis-cli 工具进行测试,其他工具可能会自动重定向

此外,还可以使用 redis-cli -c 设置自动重定向:

[root@localhost ~]# redis-cli -a cluster123456 -p 6379 -c
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
127.0.0.1:6379> get aa
-> Redirected to slot [1180] located at 192.168.56.101:6379
"bb"
3.2.2 ASK

Redis 集群进行伸缩(扩容 / 缩容)时,会进行哈希槽的迁移,当访问目标节点时,数据可能已经迁移到新的节点中,这时会产生 ASK 重定向。

在哈希槽的迁移过程中,槽中对应的多个 Key 是分批次进行移动的,而不是一次性的整体迁移,因此迁移槽中的 Key 一部分在老的服务节点,一部分在新的服务节点。当访问的 Key 正在发生迁移时,ASK 仅指示将下一个查询重定下到指定节点。

MOVED 的区别:

  • MOVED :适用于哈希槽永久由另一个节点服务,接下来的查询应该尝试指定的节点。
  • ASK :适用于哈希槽正在迁移,指示仅将下一个查询发送到指定节点。
3.2.3 客户端重定向处理

为了保持高效处理能力,Redis Cluster客户端会在本地维护当前哈希槽映射表,但是这个映射表需要保持是最新的,当客户端连接到错误的节点导致重定向时,客户端可更新本地的哈希槽映射表。

客户端通常需要在以下两种情况下进行更新:

  • 在启动时初始化映射表
  • 收到 MOVED 重定向

推荐重新获取完整的映射表,而不是更新变动的某一条数据,这样更简单高效。客户端可以通过发出CLUSTER SLOTS命令来获取一个包含哈希槽范围及其对应节点的数组。

示例:

127.0.0.1:7000> cluster slots
1) 1) (integer) 5461 # 哈希槽范围的开始
   2) (integer) 10922 # 哈希槽范围的结束
   3) 1) "127.0.0.1"  # 主节点地址端口
      2) (integer) 7001
   4) 1) "127.0.0.1" # 从节点地址端口
      2) (integer) 7004
2) 1) (integer) 0
   2) (integer) 5460
   3) 1) "127.0.0.1"
      2) (integer) 7000
   4) 1) "127.0.0.1"
      2) (integer) 7003
3) 1) (integer) 10923
   2) (integer) 16383
   3) 1) "127.0.0.1"
      2) (integer) 7002
   4) 1) "127.0.0.1"
      2) (integer) 7005

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

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

相关文章

matlab仿真 数字信号载波传输(下)

(内容源自详解MATLAB/SIMULINK 通信系统建模与仿真 刘学勇编著第七 章内容,有兴趣的读者请阅读原书) clear all M8; msg[1 4 3 0 7 5 2 6]; ts0.01; T1; %t0:ts:T; t0:ts:T-ts; %x0:ts:length(msg); x0:ts:length(msg)-ts; f…

爬虫 APP 逆向 ---> 粉笔考研

环境: 粉笔考研 v6.3.15:https://www.wandoujia.com/apps/1220941/history_v6031500雷电9 模拟器:https://www.ldmnq.com/安装 magisk:https://blog.csdn.net/Ruaki/article/details/135580772安装 Dia 插件 (作用:禁…

前端开发知识-vue

大括号里边放键值对,即是一个对象。 一、vue可以简化前端javascript的操作。 主要特点是可以实现视图、数据的双向绑定。 使用vue主要分为三个步骤: 1.javascript中引入vue.js 可以src中可以是vue的网址,也可以是本地下载。 2.在javasc…

地形材质制作(能使地面湿润)

如图,创建一个材质并写以下逻辑 Landscape Layer Blend节点能使在地形模式绘制中有三个选择,根据以上逻辑,Red是原材质,Green是绿色材质也就是草,Blue为水(这个我认为比较重要) Blue的颜色最好为这个 这个节…

董宇辉离职,我一点都不意外!只不过感觉来的太快

下面这张图,是我在半年多前写的一段随笔,没想到来的这么快! 碰巧的是今天中午,在开发者群里有两位老铁自曝,本以为能公司干到老,但公司却不给机会,已经不在是公司员工了。 最近,晓衡…

一些关于颜色的网站

欢迎来到 破晓的历程的 博客 ⛺️不负时光,不负己✈️ 1、中国传统色 2、网页颜色选择器 3、渐变色网站 4、多风味色卡生成 5、波浪生成 6、半透明磨砂框 色卡组合

苍穹外卖01

0. 配置maven (仅一次的操作 1.项目导入idea 2. 保证nginx服务器运行 (nginx.exe要在非中文的目录下) 开启服务: start nginx 查看任务进程是否存在: tasklist /fi "imagename eq nginx.exe" 关闭ngi…

SAPUI5基础知识20 - 对话框和碎片(Dialogs and Fragments)

1. 背景 在 SAPUI5 中,Fragments 是一种轻量级的 UI 组件,类似于视图(Views),但它们没有自己的控制器(Controller)。Fragments 通常用于定义可以在多个视图中重用的 UI 片段,从而提…

【数据结构--排序】

目录 一、排序概述1.1、排序的相关定义1.2、排序用到的结构与函数 二、常见排序算法2.1、冒泡算法(交换顺序)(1)算法(2)性能分析 2.2、简单选择排序(1)算法(2&#xff09…

express连接mysql

一、 安装express npm install express --save二、express配置 //引入 const express require("express"); //创建实例 const app express(); //启动服务 app.listen(8081, () > {console.log("http://localhost:8081"); });三、安装mysql npm i m…

《昇思25天学习打卡营第6天|ResNet50图像分类》

写在前面 从本次开始,接触一些上层应用。 本次通过经典的模型,开始本次任务。这里开始学习resnet50网络模型,应该也会有resnet18,估计18的模型速度会更快一些。 resnet 通过对论文的结论进行展示,说明了模型的功能&…

第2章 编译SDK

安装编译依赖 sudo apt-get update sudo apt-get install clang-format astyle libncurses5-dev build-essential python-configparser sconssudo apt-get install repo git ssh make gcc libssl-dev liblz4-tool \ expect g patchelf chrpath gawk texinfo chrpath diffstat …

springboot促进高等教育可持续发展管理平台-计算机毕业设计源码36141

摘 要 随着全球对可持续发展的日益关注,高等教育作为培养未来领导者和创新者的摇篮,其在推动可持续发展中的角色日益凸显。然而,传统的高等教育管理模式在应对复杂多变的可持续发展挑战时,显得力不从心。因此,构建一个…

stm32入门-----USART串口实现数据包的接收和发送

目录 前言 数据包 1.HEX数据包 2.文本数据包 C编程实现stm32收发数据包 1.HEX数据包的收发 2.文本数据包的收发 前言 前面几期讲解了USART串口发送数据和接收数据的原理,那本期在前面的基础上学习stm32 USART串口发送和接收数据包。本期包括两个项目&a…

数据库作业四

1. 修改 student 表中年龄( sage )字段属性,数据类型由 int 改变为 smallint : ALTER TABLE student MODIFY Sage SMALLINT; 2. 为 Course 表中 Cno 课程号字段设置索引,并查看索引: ALTER TABLE…

Linux系统下非root用户自行安装的命令切换为root权限时无法使用,提示comman not found解决办法

今天在开发的时候遇上了一个问题就是要去我们数据平台中进行数据的提取,数据存储用的是minio,一个MinIO部署由一组存储和计算资源组成,运行一个或多个 minio server 节点,共同作为单个对象存储库。独立的MinIO实例由具有单个 mini…

多区域DNS以及主从DNS的搭建

搭建多域dns服务器: 搭建DNS多区域功能(Multi-Zone DNS)主要是为了满足复杂网络环境下的多样化需求,提高DNS服务的灵活性、可扩展性和可靠性。 适应不同网络环境: 在大型组织、跨国公司或跨地域服务中,网…

微服务安全——SpringSecurity6详解

文章目录 说明SpringSecurity认证快速开始设置用户名密码基于application.yml方式基于Java Bean配置方式 设置加密方式自定义用户加载方式自定义登录页面前后端分离认证认证流程 SpringSecurity授权web授权:基于url的访问控制自定义授权失败异常处理方法授权:基于注解的访问控制…

2024上半年热门网络安全产品和工具TOP10_wiz安全产品

今年上半年,利用生成式人工智能(GenAI)的网络安全工具继续激增。许多供应商正在利用GenAI的功能来自动化安全运营中心(SOC)的工作,特别是在自动化日常活动方面,如收集威胁信息和自动创建查询。 …

element 结合 {} 实现自适应布局

通过el-row el-col 实现 例如 :xl“{ 1: 24, 2: 12, 3: 8, 4: 6 }[tableData.length] || 6” length 1 2 3 4 、代码数量为 1 2 3 4 >4 时不同卡片数量时尺寸的配置