0x02.Redis 集群的实现原理是什么?

回答重点

Redis 集群(Redis cluster)是通过多个 Redis 实例组成的,每个主节点实例负责存储部分的数据,并且可以有一个或多个从节点作为备份

具体是采用哈希槽(Hash Slot)机制来分配数据,将整个键空间划分为 16384 个槽(slots)。每个 Redis 主节点实例负责一定范围的哈希槽,数据的 key 经过 CRC16-CCITT 哈希算法计算后对 16384 取余即可定位到对应的节点。

客户端在发送请求时,会通过集群的任意节点进行连接,如果该节点存储了对应的数据则直接返回,反之该节点会根据请求的键值计算哈希槽并路由到正确的节点。现代 Redis 客户端通常会缓存槽位映射信息,避免频繁重定向。

简单来说,集群就是通过多台机器分担单台机器上的压力,同时通过主从复制提供高可用性。

扩展知识

Redis 集群中节点之间的信息如何同步?

Redis 集群内每个节点都会保存集群的完整拓扑信息,包括每个节点的 ID、IP 地址、端口、负责的哈希槽范围等。

节点之间使用 Gossip 协议进行状态交换,以保持集群的一致性和故障检测。每个节点会周期性地发送 PING 和 PONG 消息,交换集群信息,使得集群信息得以同步。

Gossip 的优点

  • 最终一致性:Gossip 协议能够在一段时间后使集群信息达成一致,虽然传播速度不如中心化方案快,但网络开销更小。
  • 降低网络负担:由于信息是以随机节点间的对话方式传播,避免了集中式的状态查询,从而降低了网络流量。

Gossip 协议

Gossip 主要特点

  1. 分布式信息传播:每个节点定期向其他节点发送其状态信息,确保所有节点对集群的状态有一致的视图。
  2. 低延迟和高效率:Gossip 协议设计为轻量级的通信方式,能够快速传播信息,减少单点故障带来的风险。
  3. 去中心化:没有中心节点,所有节点平等地参与信息传播,提高了系统的鲁棒性。

工作原理

  1. 状态报告:每个节点在特定的时间间隔内,向随机选择的其他节点发送其自身的状态信息,包括节点的主从关系、槽位分布等。
  2. 信息更新:接收到状态信息的节点会根据所接收到的数据更新自己的状态,并将更新后的状态继续传播给其他节点。
  3. 节点检测:通过周期性交换状态信息,节点可以检测到其他节点的存活状态。如果某个节点未能在预定时间内响应,则该节点会被标记为故障节点。
  4. 容错处理:在检测到节点故障后,集群中的其他节点可以采取措施(如重新分配槽位)以保持系统的高可用性。

Redis 集群分片原理图示

Redis 集群会将数据分散到 16384(2^14)个哈希槽中,集群中的每个主节点负责一定范围的哈希槽,在 Redis 集群中,使用 CRC16-CCITT 哈希算法计算键的哈希槽,以确定该键应存储在哪个节点。

集群哈希槽分片如下图所示:

在这里插入图片描述

每个节点会拥有一部分的槽位,然后对应的键值会根据其本身的 key,映射到一个哈希槽中,其主要流程如下:

  • 根据键值的 key,按照 CRC16-CCITT 算法计算一个 16 bit 的值,然后将 16 bit 的值对 16384 进行取余运算,最后得到一个对应的哈希槽编号。
  • 值得注意的是,Redis 支持哈希标签(Hash Tags)机制,即如果键名中包含 “{…}” 格式的内容,那么只有花括号内的内容会被用来计算哈希槽,这样可以确保相关联的键被分配到同一个槽中。
  • 根据每个节点分配的哈希槽区间,对应编号的数据落在对应的区间上,就能找到对应的分片实例。

为了方便大家理解,我这里画一个对应的关系图,以三个节点为例:

Redis 哈希槽映射图


CRC16(Key1) % 16384 = 123
CRC16(Key2) % 16384 = 8275
CRC16(Key3) % 16384 = 12319
Redis实例 1(0 ~ 5460)
Redis实例 2(5461 ~ 10922)
Redis实例 3(10923 ~ 16383)

这里还有一点需要强调下,Redis 客户端可以访问集群中任意一台实例,正常情况下这个实例包含这个数据
但如果槽被转移了,客户端还未来得及更新槽的信息,当前实例没有这个数据,则返回 MOVED 响应给客户端,将其重定向到对应的实例(因 Gossip 协议确保集群内每个节点都会保存集群的完整拓扑信息)。

Redis 集群中存储 key 示例

假设我们有一个 Redis 集群,包含三个主节点(Node1、Node2、Node3),它们分别负责以下哈希槽:

  • Node1: 哈希槽 0-5460
  • Node2: 哈希槽 5461-10922
  • Node3: 哈希槽 10923-16383

现在要存储一个键为 user:1001 的数据。

计算哈希槽
  1. 使用 CRC16-CCITT 哈希算法计算 user:1001 的 CRC16 值。
  2. 假设计算结果为 12345。
  3. 然后,计算该值对应的哈希槽:
    • 哈希槽 = 12345 % 16384 = 12345。
确定目标节点
  • 12345 落在 Node3 的负责范围(10923-16383),因此,user:1001 会被存储在 Node3 中。

Redis 集群中请求 key 示例(客户端直接连接的并不是对应 key 的节点)

如果客户端连接的是集群的 Node1,但需要访问存储在 Node3 的键 user:1001,查询过程如下:

查询过程

1)计算哈希槽

  • 客户端使用 CRC16-CCITT 算法计算 user:1001 的哈希值(假设为 12345)。
  • 计算哈希槽:12345 % 16384 = 12345。

2)查询请求

  • 因为客户端连接的是集群中的 Node1,所以客户端发送查询命令 GET user:1001 到 Node1。

3)Node1 响应

  • Node1 检测到请求的键 user:1001 属于 Node3,返回一个 MOVED 错误,指示客户端请求的键在另一个节点上。MOVED 错误中会返回目标节点的信息(例如,Node3 的 IP 和端口)。

4)客户端处理

  • 现代 Redis 客户端会缓存此槽位映射信息,后续对该槽的请求会直接发送到正确的节点,避免重定向。
  • 第一次收到 MOVED 错误时,客户端会连接到目标节点并更新槽位映射缓存。

5)发送查询请求到正确节点

  • 客户端向 Node3 发送 GET user:1001

6)获取结果

  • Node3 查询到 user:1001 的值(假设为 {"name": "stormsha", "age": 16}),并返回结果。

为什么 Redis 哈希槽节点的数目是 16384 呢?

1)首先是消息大小的考虑

正常的心跳包需要带上节点完整配置数据,心跳还是比较频繁的,所以需要考虑数据包的大小,如果使用 16384 数据包只要约 2KB,如果用了 65536 则需要约 8KB。

实际上槽位信息使用一个长度为 16384 位的位图(bitmap)来表示,节点拥有哪个槽位,就将对应位置的位设置为 1,否则为 0。

Redis 心跳消息(CLUSTERMSG)数据结构如下所示:

typedef struct {char sig[4];              /* 信息标识 */uint32_t totlen;          /* 消息总长度 */uint16_t ver;             /* 协议版本 */uint16_t type;            /* 消息类型, 用于区分meet,ping,pong等消息 */uint16_t count;           /* 消息体包含的节点数量, 仅用于meet,ping,pong消息类型*/uint64_t currentEpoch;    /* 当前发送节点的配置纪元 */uint64_t configEpoch;     /* 主节点/从节点的主的配置纪元 */char sender[CLUSTER_NAMELEN]; /* 发送节点的nodeId */unsigned char myslots[CLUSTER_SLOTS/8]; /* 发送节点负责的槽信息 */char slaveOf[CLUSTER_NAMELEN]; /* 如果是从节点,记录主节点的nodeId */uint16_t port;            /* 端口号 */uint16_t flags;           /* 发送节点标识,区分主从角色,是否下线等 */unsigned char state;      /* 发送节点的集群状态 */unsigned char mflags[3];  /* 消息标识 */union clusterMsgData data /* 消息正文 */;
} clusterMsg;

这里我们看到一个重点,即在消息头中最占空间的是 myslots[CLUSTER_SLOTS/8]

  • 当槽位为 65536 时,这部分大小: 65536÷8=8192 字节 ≈8KB
  • 当槽位为 16384 时,这部分大小: 16384÷8=2048 字节 ≈2KB

如果槽位为 65536,这个心跳消息的头部就太大了,在高频率通信的集群环境中会显著增加网络负担。

2)集群规模的考虑

根据 Redis 作者的说明,集群不太可能会扩展超过 1000 个节点,而每个主节点应该管理相当数量的哈希槽。如果使用 16384 个槽位:

  • 100 个节点集群:平均每个节点管理约 164 个槽位
  • 1000 个节点集群:平均每个节点管理约 16 个槽位

这个数量既能满足大多数集群规模需求,又不会因为槽位过少而影响数据分布均衡性。

3)内存占用的平衡

Redis 作为内存数据库,对内存使用的效率非常关注。16384 个槽位的设计在集群功能和资源消耗之间取得了很好的平衡:足够多的槽位保证良好的数据分布,同时槽位映射的内存占用和网络传输开销都保持在合理范围内。

好的,以下是测试题目解析部分分开的版本:


✅ Redis 集群选择题(共 4 题)

1. Redis 集群采用什么机制来分配数据到不同的节点? ( )
A. 哈希槽机制
B. 主备机制
C. 哈希链机制
D. 分段机制

2. Redis 集群中有多少个哈希槽? ( )
A. 2048
B. 8192
C. 16384
D. 32768

3. Redis 集群中的节点之间使用什么协议进行状态同步和故障检测? ( )
A. TCP/IP 协议
B. HTTP 协议
C. UDP 协议
D. Gossip 协议

4. 在 Redis 集群中,当客户端请求的键值对不在连接的节点上时,返回的错误类型是什么? ( )
A. ERROR
B. MOVED
C. NOT_FOUND
D. FORBIDDEN

📘 答案与解析

1. 正确答案:A
解析:Redis 集群通过哈希槽机制进行数据分配,避免单点瓶颈,将键映射到 16384 个槽中,再分配到不同节点。


2. 正确答案:C
解析:Redis 集群采用固定的 16384 个哈希槽,这个值是 2¹⁴,设计用于在带宽与灵活性之间做出平衡。


3. 正确答案:D
解析:Redis 集群使用 Gossip 协议实现去中心化状态同步和故障检测,各节点定期交换信息。


4. 正确答案:B
解析:当客户端请求的 key 不在当前节点时,Redis 返回 MOVED 重定向错误,引导客户端访问正确节点。


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

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

相关文章

基本的DOS命令

一.打开CMD方式: winR 输入cmd 开始系统命令提示符 在任意文件夹下,shift+鼠标右击,在此处打开命令 资源管理器的地址栏前面输入cmd 以管理员身份打开cmd:选择以管理员方式运行 二.常用的Dos命令 #盘符切换 盘符…

深度剖析:架构评估的常用方法与应用

架构评估是确保系统架构满足需求、性能和质量等方面要求的重要环节,以下是一些常见的架构评估方法的详细介绍: 一、基于调查问卷或检查表的评估方法 1.方法概述:该方法通过设计一系列针对性的问题或检查项,形成问卷或检查表&…

代码随想录算法训练营第十六天

LeetCode题目: 530. 二叉搜索树的最小绝对差501. 二叉搜索树中的众数236. 二叉树的最近公共祖先3272. 统计好整数的数目(每日一题) 其他: 今日总结 往期打卡 530. 二叉搜索树的最小绝对差 跳转: 530. 二叉搜索树的最小绝对差 学习: 代码随想录公开讲解 问题: 给你一个二叉搜…

基于双闭环PID控制器的永磁同步电机控制系统匝间故障Simulink仿真

欢迎微♥关注“电击小子程高兴的MATLAB小屋”获取巨额优惠 1.模型简介 本仿真模型基于MATLAB/Simulink(版本MATLAB 2013Rb)软件。建议采用matlab2013 Rb及以上版本打开。(若需要其他版本可联系代为转换,高于该版本的matlab均可正…

02-libVLC的视频播放器:播放音视频文件以及网络流

libvlc_new(0, nullptr)功能:创建并初始化libVLC的核心实例,是使用所有libVLC功能的前提。 参数:第一个参数:参数数量(通常设为0)第二个参数:参数列表(通常为nullptr,表示使用默认配置)返回值:成功返回libvlc_instance_t*指针,失败返回nullptr。注意事项:可通过参…

2025蓝桥杯省赛C++B组解题思路

由于题面还没出来,现在先口胡一下思路 填空题直接打表找规律或者乱搞一下就能出,从大题开始说。 1,题意: 给你一个数组,这个数组里有几个数可以被一个连续递增的数字区间求和得出 思路:诈骗题,显…

防止邮件伪造的策略 SPF 介绍

SPF是Sender Policy Framework的缩写,即发件人策略框架,是一种用于防止电子邮件伪造的技术,用来验证发件人邮箱域名的真实性。以下是关于它的详细说明: 1. 定义与作用 SPF是一种电子邮件验证系统,它通过在域名的DNS记…

JavaScript Symbol与BigInt

目录 Symbol类型 一、Symbol 的核心特性 1. 唯一性 2. 不可变性 3. 不可枚举性 二、创建 Symbol 1. 基础创建 2. 全局 Symbol 注册表 三、Symbol 作为对象属性 1. 定义 Symbol 属性 2. 遍历 Symbol 属性 四、内置 Symbol 值 五、实际应用场景 1. 避免属性名冲突 …

AI Agent工程师认证-学习笔记(3)——【多Agent】MetaGPT

学习链接:【多Agent】MetaGPT学习教程 源代码链接(觉得很好,star一下):GitHub - 基于MetaGPT的多智能体入门与开发教程 MetaGPT链接:GitHub - MetaGPT 前期准备 1、获取MetaGPT (1)使用pip获取MetaGPT pip install metagpt==0.6.6#或者在国内加速安装镜像 #pip in…

【leetcode hot 100 416】分割等和子集

解法一:(动态规划)①定义:dp[i]表示是否可以在nums找到元素之和为i,dp[sum/21] ②初始状态:dp[0]true;dp[i]false ③状态转移方程:dp[i] dp[i] || dp[i - num]; class Solution {public boole…

高中数学联赛模拟试题精选第2套几何题(改编)

在 △ A B C \triangle ABC △ABC 中, 点 M M M 是边 A C AC AC 的中点. 在线段 A M AM AM, C M CM CM 上分别取点 P P P, Q Q Q, 使得 P Q A C / 2 PQAC/2 PQAC/2. 设 △ A B Q \triangle ABQ △ABQ 的外接圆与边 B C BC BC 相交于点 X X X, △ B C P \triangle …

UWB双通道隧道人员定位方案

技术基础:UWB(超宽带技术) 定义:UWB(Ultra-Wideband)是一种通过纳秒级窄脉冲传输数据的无线通信技术,占用500MHz以上的超宽频段。 核心优势: 高精度定位:时间分辨率极高&…

Linux 入门八:Linux 多进程

一、概述 1.1 什么是进程? 在 Linux 系统中,进程是程序的一次动态执行过程。程序是静态的可执行文件,而进程是程序运行时的实例,系统会为其分配内存、CPU 时间片等资源。例如,输入 ls 命令时,系统创建进程…

MTCNN 人脸识别

前言 此处介绍强大的 MTCNN 模块,给出demo,展示MTCNN 的 OOP, 以及ROS利用 C 节点,命令行调用脚本执行实际工作的思路。 MTCNN Script import argparse import cv2 from mtcnn import MTCNN import osclass MTCNNProcessor:def…

01_核心系统下的技术原理解析

15年前,基本上国内的核心系统被C垄断,基本上是IBM的那套东西,场景也是比价复杂,这里不再赘述,TPS太过于庞大,技术上确实比较复杂。为此我这里抛砖引玉,说下对应的支付系统: &#x…

Python 实现最小插件框架

文章目录 Python 实现最小插件框架1. 基础实现项目结构plugin_base.py - 插件基类plugins/hello.py - 示例插件1plugins/goodbye.py - 示例插件2main.py - 主程序 2. 更高级的特性扩展2.1 插件配置支持2.2 插件依赖管理2.3 插件热加载 3. 使用 setuptools 的入口点发现插件3.1 …

电感详解:定义、作用、分类与使用要点

一、电感的基本定义 电感(Inductor) 是由导线绕制而成的储能元件,其核心特性是阻碍电流变化,将电能转化为磁能存储。 基本公式: 自感电动势: E -L * (di/dt) (L:电感值&#xff0c…

运行一次性任务与定时任务

运行一次性任务与定时任务 文章目录 运行一次性任务与定时任务[toc]一、使用Job运行一次性任务1.创建一次性任务2.测试一次性任务3.删除Job 二、使用CronJob运行定时任务1.创建定时任务2.测试定时任务3.删除CronJob 一、使用Job运行一次性任务 1.创建一次性任务 (…

对话记忆(Conversational Memory)

一、引言 在与大型语言模型(LLM)交互的场景中,对话记忆(Conversational Memory)指的是模型能够在多轮对话中保留、检索并利用先前上下文信息的能力。这一机制使得对话系统不再仅仅是“问答机”,而是能够持…

【HD-RK3576-PI】VNC 远程桌面连接

在当今数字化时代,高效便捷的操作方式是技术爱好者与专业人士的共同追求。对于使用 HD-RK3576-PI微型单板计算机的用户而言,当面临没有显示屏的场景时,如何实现远程操作桌面系统呢?别担心,VNC 远程桌面连接将为你解决这…