深入了解redis的哈希槽的知识
目录
1、哈希算法分类
1.1、简单哈希算法
1.2、一致性哈希算法
1、原理:
2、解决问题
3、数据倾斜问题
4、虚拟节点
2. 哈希槽
2.1、介绍
2. 2、作用
1、数据分片(Sharding)
2、高可用性(HA)
3、动态扩展
3. 哈希槽的分配与迁移
3.1、初始分配
3.2、迁移过程
3.3、原理
4. 与一致性哈希的区别
5. 客户端如何利用哈希槽
6. 查看哈希槽信息
前言
Redis 哈希槽(Hash Slot)是 Redis Cluster 实现分布式数据存储的核心机制之一。它是 Redis 集群用于将键空间划分为多个逻辑单元(即槽位),并将这些单元分配到不同节点的策略。
关于更多redis cluster的介绍,可参考:对于Redis集群部署模式的不同实现_redis 集群-CSDN博客
1、哈希算法分类
1.1、简单哈希算法
假设有三台机,数据落在哪台机的算法为:c = Hash(key) % 3
例如 key A 的哈希值为4,4 % 3 = 1,则落在第二台机。Key ABC 哈希值为11,11 % 3 = 2,则落在第三台机上。
利用这样的算法,假设现在数据量太大了,需要增加一台机器。A 原本落在第二台上,现在根据算法4 % 4 = 0,落到了第一台机器上了,但是第一台机器上根本没有 A 的值。
这样的算法会导致增加机器或减少机器的时候,引起大量的缓存穿透,造成雪崩。
1.2、一致性哈希算法
在一致性哈希算法中,整个哈希空间是一个虚拟圆环。从 0 ~ 2^32-1 代表的分别是一个个的节点,这个环也叫哈希环。
如下图所示:
假设有四个节点 Node D0,D1,D2,D3,经过 ip 地址的哈希计算,它们的位置如下:
1、原理:
然后通过数据 key 找到对应的服务器然后存储了,通过数据 key 的哈希值落在哈希环上的节点,如果命中了机器节点就落在这个机器上,否则落在顺时针直到碰到第一个机器。
如下图所示 : A 的哈希值落在了 D2 节点的前面,往下找落在了 D2 机器上,D的哈希值 在 D1 节点的前面,往下找到了 D1 机器,B的哈希值刚好落在了D1 节点上,依次~~~
2、解决问题
解决当机器减少或增加的时候,大面积的数据重新哈希的问题。
1、当节点宕机时,该节点的数据记录会被定位到下一个节点上,其它的数据都没有被影响到。
2、当新增节点的时候 ,相关区间内的数据记录就需要重新哈希,其他位置的数据不需要改变。
3、数据倾斜问题
一致性Hash算法在服务节点太少时,容易因为节点分部不均匀而造成数据倾斜(被缓存的对象大部分集中缓存在某一台服务器上)问题。
比如只有 2 台机器,这 2 台机器离的很近,那么顺时针第一个机器节点上将存在大量的数据,第二个机器节点上数据会很少。
如下图所示,D0 机器承载了绝大多数的数据
4、虚拟节点
为了避免出现数据倾斜问题,一致性 Hash 算法引入了虚拟节点的机制,也就是每个机器节点会进行多次哈希,最终每个机器节点在哈希环上会有多个虚拟节点存在,使用这种方式来大大削弱甚至避免数据倾斜问题。
同时数据定位算法不变,只是多了一步虚拟节点到实际节点的映射。
如下图所示:
例如定位到“D1#1”、“D1#2”、“D1#3”三个虚拟节点的数据均定位到 D1 上。这样就解决了服务节点少时数据倾斜的问题。
在实际应用中,通常将虚拟节点数设置为32甚至更大,因此即使很少的服务节点也能做到相对均匀的数据分布。这也是 Dubbo 负载均衡中有一种一致性哈希负载均衡的实现思想。
2. 哈希槽
2.1、介绍
Redis Cluster 是 Redis 的分布式架构,它将数据分布在多个 Redis 实例(节点)上。为了实现数据分片,Redis Cluster 使用了哈希槽(Hash Slot)机制。
如下图所示:
1、总槽数:
Redis 集群将键空间划分为 16384 个哈希槽(编号从 0
到 16383
)。 这个数能够平衡操作成本和系统性能。
2、键的映射规则:
每个键通过 CRC16
算法计算哈希值,然后对 16384
取模,得到所属的槽位。
- 例如:
slot = CRC16("key") % 16384
3、槽到节点的映射:
Redis Cluster 中的每个节点负责管理若干个哈希槽。
2. 2、作用
1、数据分片(Sharding)
- 每个 Redis 节点负责一部分哈希槽(例如,3 个节点可能各负责约 5461 个槽)。
- 键的归属:键的哈希槽决定了它存储在哪个节点。客户端或集群会根据槽位找到对应的节点。
2、高可用性(HA)
- 如果某个节点失效,它的哈希槽会被重新分配到其他节点(通过故障转移或手动迁移)。
- 客户端会缓存槽位到节点的映射关系,减少查询重定向的开销。
3、动态扩展
- 添加或删除节点时,可以通过迁移哈希槽来平衡数据分布,而无需重新计算所有键的哈希值。
3. 哈希槽的分配与迁移
关于分配如下图所示:
3.1、初始分配
集群初始化时,管理员通过工具(如 redis-cli --cluster
)将哈希槽分配给各个节点。
在 Redis 集群中,哈希槽的分配和计算是由 Redis 服务器自动完成的。当你执行一个写入或读取操作时,Redis 会根据键的名称自动计算其所属的哈希槽(slot),并将其路由到对应负责该槽的节点上。
✅ 使用 redis-cli --cluster
初始化哈希槽的步骤
1. 准备工作
启动 Redis 节点:确保所有节点已经启动并配置为集群模式。
# 示例:启动 3 个主节点和 3 个从节点(端口分别为 6379, 6380, 6381 和 6389, 6390, 6391)
redis-server --port 6379 --cluster-enabled yes --cluster-config-file nodes-6379.conf
redis-server --port 6380 --cluster-enabled yes --cluster-config-file nodes-6380.conf
redis-server --port 6381 --cluster-enabled yes --cluster-config-file nodes-6381.conf
redis-server --port 6389 --cluster-enabled yes --cluster-config-file nodes-6389.conf
redis-server --port 6390 --cluster-enabled yes --cluster-config-file nodes-6390.conf
redis-server --port 6391 --cluster-enabled yes --cluster-config-file nodes-6391.conf
2. 使用 redis-cli --cluster create
命令初始化集群
运行以下命令,将哈希槽分配到主节点,并建立主从关系:
redis-cli --cluster create \127.0.0.1:6379 127.0.0.1:6380 127.0.0.1:6381 \127.0.0.1:6389 127.0.0.1:6390 127.0.0.1:6391 \--cluster-replicas 1 \--cluster-yes
参数说明
--cluster create
:创建集群。127.0.0.1:6379 ...
:列出所有节点的地址。--cluster-replicas 1
:每个主节点分配 1 个从节点(共 3 个主节点 + 3 个从节点)。--cluster-yes
:自动确认操作(无需手动输入yes
)。
输出示例
>>> Performing hash slots allocation on 6 nodes...
Master[0] -> Slots 0 - 5460 (5461 slots)
Master[1] -> Slots 5461 - 10922 (5462 slots)
Master[2] -> Slots 10923 - 16383 (5461 slots)
Adding replica 127.0.0.1:6389 to 127.0.0.1:6379
Adding replica 127.0.0.1:6390 to 127.0.0.1:6380
Adding replica 127.0.0.1:6391 to 127.0.0.1:6381
3. 验证集群状态
使用以下命令检查集群是否初始化成功:
redis-cli -h 127.0.0.1 -p 6379 cluster info
输出:
cluster_state:ok
cluster_slots_assigned:16384
cluster_slots_ok:16384
cluster_slots_pfail:0
cluster_slots_fail:0
3.2、迁移过程
当需要调整负载时,可以通过
CLUSTER SETSLOT
或redis-cli --cluster reshard
命令迁移槽位。迁移过程中,源节点会逐步将数据(键值对)复制到目标节点。
迁移数据,如下图所示:
添加新节点并迁移槽位
如果需要扩展集群,可以使用以下命令:
redis-cli --cluster add-node 127.0.0.1:6392 127.0.0.1:6379
redis-cli --cluster reshard 127.0.0.1:6379
总结
通过
redis-cli --cluster create
命令,你可以快速初始化 Redis 集群并分配哈希槽。确保节点配置正确、网络可达,并遵循最小主节点数要求。初始化完成后,使用CLUSTER INFO
和CLUSTER NODES
验证集群状态。
3.3、原理
1.键的分配:
当你在Redis中插入一个键时,Redis会通过 CRC16 算法计算该键的哈希值,并映射到某个哈希槽。例如:
键 user:1001 的哈希值为 12582,对应哈希槽 12582。
键 order:5001 的哈希值为 7892,对应哈希槽 7892。
2.节点与槽的绑定:
Redis集群启动时,节点会声明自己管理的哈希槽范围。
例如:
节点 A 管理 0-5460 槽。
节点 B 管理 5461-10922 槽。
节点 C 管理 10923-16383 槽。
3.键的查询:
客户端访问键时,Redis首先根据键的哈希值找到对应的哈希槽,再定位到具体的节点。
4.槽的迁移:
如果一个节点的压力过大,Redis可以通过槽迁移功能将某些槽转移到其他节点,减轻压力。
4. 与一致性哈希的区别
可参考如下:
5. 客户端如何利用哈希槽
1、缓存映射关系:
客户端会缓存槽位到节点的映射表,减少对集群节点的频繁查询。
2、处理 MOVED 错误:
当客户端请求一个键时,集群会根据键的哈希槽编号将请求路由到对应的节点。如果键的哈希槽不在请求节点上,节点会返回
MOVED <slot> <ip:port>
错误,告知客户端正确的目标节点。
客户端根据 MOVED
响应重新发送请求到目标节点,客户端根据此信息更新缓存并重试。。
3、支持多键操作:
Redis 要求多键操作(如
MGET
、MSET
)的所有键必须位于同一个槽位,否则会报错。
解决方法:使用 哈希标签(Hash Tag)
如果键中包含 {}
,Redis只会使用 {}
中的内容计算哈希槽。例如:
- 键
user:{1001}
和order:{1001}
将落入相同的哈希槽。
以下是一个 Java 示例代码,用于连接 Redis 集群,并输出当前集群中每个节点负责的哈希槽分配情况。
✅ Maven 依赖配置
首先,你需要在项目中引入 Jedis 依赖:
<dependency><groupId>redis.clients</groupId><artifactId>jedis</artifactId><version>4.4.0</version>
</dependency>
🧪 Java 示例代码
import redis.clients.jedis.HostAndPort;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.Protocol;
import redis.clients.jedis.exceptions.JedisConnectionException;import java.util.*;public class RedisClusterSlotViewer {public static void main(String[] args) {// Redis 集群中的任意节点(可以是主节点或从节点)String host = "127.0.0.1";int port = 6379;try (Jedis jedis = new Jedis(host, port)) {// 确保连接的是集群模式String mode = jedis.info("cluster").toLowerCase();if (!mode.contains("cluster")) {System.out.println("当前 Redis 不是集群模式");return;}// 执行 CLUSTER SLOTS 命令List<List<?>> clusterSlots = jedis.clusterSlots();// 输出每个节点负责的哈希槽范围System.out.println("Redis Cluster Slot 分配如下:");for (List<?> slotRange : clusterSlots) {int startSlot = (Integer) slotRange.get(0);int endSlot = (Integer) slotRange.get(1);List<HostAndPort> nodes = parseNodeInfo(slotRange);for (HostAndPort node : nodes) {System.out.printf("槽位范围: [%d - %d] -> 节点: %s:%d%n",startSlot, endSlot, node.getHost(), node.getPort());}}} catch (JedisConnectionException e) {System.err.println("无法连接到 Redis 集群,请确认集群正在运行且网络可达");e.printStackTrace();}}/*** 解析 CLUSTER SLOTS 返回的节点信息*/private static List<HostAndPort> parseNodeInfo(List<?> slotRange) {List<HostAndPort> nodes = new ArrayList<>();List<?> nodesList = (List<?>) slotRange.get(2);for (Object nodeObj : nodesList) {List<String> nodeInfo = (List<String>) nodeObj;String host = nodeInfo.get(0);int port = Integer.parseInt(nodeInfo.get(1));nodes.add(new HostAndPort(host, port));}return nodes;}
}
📌 示例输出(假设集群为 3 节点)
Redis Cluster Slot 分配如下:
槽位范围: [0 - 5460] -> 节点: 127.0.0.1:6379
槽位范围: [5461 - 10922] -> 节点: 127.0.0.1:6380
槽位范围: [10923 - 16383] -> 节点: 127.0.0.1:6381
6. 查看哈希槽信息
-
查看槽位分配:
redis-cli -h <host> -p <port> cluster slots
输出示例:
1) 1) (integer) 02) (integer) 54603) 1) 1) "127.0.0.1"2) (integer) 63793) "a1b2c3d4..."
查看节点状态:
redis-cli -h <host> -p <port> cluster nodes
总结
Redis 哈希槽是集群实现分布式存储的核心机制,通过固定槽位数量和动态迁移策略,解决了传统哈希分片中节点增减导致的数据迁移问题。
理解哈希槽的分配规则和客户端交互方式,是构建高效 Redis 集群的关键。
参考文章:
1、redis相关知识——一致性哈希、哈希槽_一个哈希槽能存储多少数据-CSDN博客
相关文章:

深入了解redis的哈希槽的知识
目录 1、哈希算法分类 1.1、简单哈希算法 1.2、一致性哈希算法 1、原理: 2、解决问题 3、数据倾斜问题 4、虚拟节点 2. 哈希槽 2.1、介绍 2. 2、作用 1、数据分片(Sharding) 2、高可用性(HA) 3…...

农业机械化、电气化和自动化知网英文普刊:1天录用,2周见刊发表!
CSP科学出版社,旨在通过为研究人员提供最佳环境来发表、参考、阅读和引用他们的作品,从而为科学界服务。现已与科检易学术达成出版战略合作,现在联合共同出版高质量学术水平的期刊,为方便广大科研学者投稿方便,现已经建…...
java将rtsp转成flv在浏览器播放
1、添加maven依赖 <dependency> <groupId>io.github.javpower</groupId> <artifactId>rtsp-converter-flv-spring-boot-starter</artifactId> <version>1.5.9.2</version> </dependency> 2、在配置application.ymlÿ…...

Docker-Compose使用自定义网桥后在OpenWrt系统中容器无法访问网络解决方案
Docker-Compose使用自定义bridge网桥后在OpenWrt系统中容器无法访问网络解决方案 示例compose描述文件如下,注意最后网络配置: # docker-compose --env-file .env.yoko.prod.local up -d services:...postgres:image: kuluseky/postgres-zhparser-post…...

界面组件DevExpress WPF中文教程:Grid - 行和卡片
DevExpress WPF拥有120个控件和库,将帮助您交付满足甚至超出企业需求的高性能业务应用程序。通过DevExpress WPF能创建有着强大互动功能的XAML基础应用程序,这些应用程序专注于当代客户的需求和构建未来新一代支持触摸的解决方案。 无论是Office办公软件…...

Qt enabled + geometry 属性(2)
文章目录 enabled属性可用与禁用的概念API接口代码演示 阐述说明1. 先简单描述下要如何演示出上面两个接口的效果(思路)2. 事先规范按钮对象的命名3. 定义两个按钮对象的槽函数 动图演示效果4. widget.cpp geometry属性预备知识API接口上下左右移动 ta…...

Llamaindex自学笔记(完)
Llamaindex框架主要做RAG,工作流用LangGraph做 换源: -i https://pypi.mirrors.ustc.edu.cn/simple/环境搭建: conda create -n llamaindex python3.12 conda activate llamaindexpip install llama-index pip install llama-cloud-servic…...
安全生态与职业跃迁
18. 网络安全产业生态 18.1 全球安全产业链解析 核心参与者角色 安全厂商: 终端安全:CrowdStrike、SentinelOne(EDR/XDR) 网络防御:Palo Alto Networks、Fortinet(NGFW/SASE) 云安全&#…...

飞书知识问答深度测评:企业AI应用落地的“范本级”产品
前言 当 AI 逐渐从技术前沿走向日常办公,我们最常听到的一个词是“效率提升”。但真正能做到降本增效、让企业员工切实受益的 AI 产品,仍属少数。尤其是在组织内部知识管理这一块,大多数企业仍停留在“搜索靠关键词、记录靠记忆、协作靠问人…...

draw.io的基础与进阶使用指南
前言 一、Draw.io 简介 Draw.io 是一款功能强大的绘图工具,支持在线使用和本地安装。它提供了丰富的模板和形状元素,能够绘制流程图、UML 图、甘特图、网络图等多种图形。Draw.io 的文件格式支持可编辑的矢量图和位图,方便后续修改 draw.io的…...
clang的介绍与使用
一、Clang 简介 Clang 是一个开源的 C/C/Objective-C 编译器前端,基于 LLVM(Low Level Virtual Machine) 项目开发。它被设计为替代传统 GCC 的现代化编译器,具有以下特点: 高性能:编译速度快,…...
GD32 IIC(I2C)通信(使用示例为SD2068)
一、前言 最近需要用到GD32的I2C通信,虽然是第一次做I2C通信,但是GD32完整的标准库有现存的I2C通信示例,虽然示例是EEPROM的通信,但是调用的函数应该是大差不差,所以上手比较简单,这里简单记录一下笔记&…...

Sanitizers
一、简介 sanitizers 是谷歌提供的一套开源工具,能够发现堆栈读写溢出、内存泄漏、线程数据竞争和死锁等问题。包括: AddressSanitizers (Asan):检测地址相关问题,如use-after-free,heap-buffer-overflow, stack_buffer_overflow,use_after_…...

pip代理出现问题 ProxyError
WARNING: Retrying (Retry(total4, connectNone, readNone, redirectNone, statusNone)) after connection broken by ‘ProxyError(‘Cannot connect to proxy.’, NewConnectionError(’<pip._vendor.urllib3.connection.HTTPSConnection object at 0x7f8347ad5ae0>: F…...
Ubuntu-多显示器黑屏问题及nvidia显卡驱动安装
Ubuntu-多显示器黑屏问题及nvidia显卡驱动安装 多显示器黑屏问题查看系统显卡信息多显示器黑屏问题 当通过HDMI为Ubuntu加入显示器时,发现新加入的显示器黑屏,更改设置里的显示器属性也无法解决。 该黑屏的原因是系统没有安装显卡驱动,因此需要安装驱动。 查看系统显卡信息…...

vue+threeJS 创建镂空球体(SphereGeometry)
嗨,我是小路。今天主要和大家分享的主题是“vuethreeJS 创建镂空球体(SphereGeometry)”。 上次看到一个做镂空球体的项目,自己也准备尝试着做一做。今天终于做完了,并对这个项目进行梳理。 镂空球体示例效果…...

[ Qt ] | 常见控件(一)
目录 Widget enable geometry 标题中的:有一不一定有二,但是有一说明还没结束。 Widget 控件(Widget),是界面上各种元素,各种部分的统称。 Qt中的控件都是继承自QWidget这个类,是Qt控件体系中,通用的…...

【八股战神篇】Java虚拟机(JVM)高频面试题
目录 专栏简介 一 请解释Java虚拟机(JVM)及其主要功能 延伸 1. JVM的基本概念 2. JVM的主要功能 二 对象创建的过程了解吗 延伸 1.Java 创建对象的四种常见方式 三 什么是双亲委派模型 延伸 1.双亲委派机制的作用: 2.双亲委派模型的核心思想: 3.双亲委派模型的…...
Pycharm-jupyternotebook不渲染
解决方案: https://youtrack.jetbrains.com/issue/PY-54244 import plotly.io as pio pio.renderers.default "vscode"...
lanqiaoOJ 4330:欧拉函数模板
【题目来源】 https://www.lanqiao.cn/problems/4330/learning/ 【问题描述】 这是一道模板题。 首先给出欧拉函数的定义:即 φ(n) 表示的是小于等于 n 的数中和 n 互质的数的个数。 比如说 φ(6)2,当 n 是质数的时候,显然有φ(n)n-1。 【题…...

NDVI谐波拟合(基于GEE实现)
在遥感影像中,我们常用 NDVI(归一化植被指数)来衡量地表植被的绿度。它简单直观,是生态监测、农情分析的基础工具。但你是否注意到: NDVI 虽然“绿”,却常常“乱”。 因为云层、观测频率、天气干扰…...
《虚拟即真实:数字人驱动技术在React Native社交中的涅槃》
当React Native与数字人驱动技术相遇,它们将如何携手塑造社交应用中智能客服与虚拟主播的自然交互呢?这正是本文要深入探讨的话题。 React Native是Facebook开源的一个用于构建原生移动应用的框架,它允许开发者使用JavaScript和React编写代码…...

南京邮电大学《智能控制技术》期末抢救(上)
一、智能控制的提出 传统控制方法包括经典控制和现代控制——基于被控对象精确模型的控制方式,缺乏灵活性和应变能力,适于解决线性、时不变性等相对简单的控制问题。传统控制方法在实际应用中遇到很多难解决的问题,主要表现以下几点ÿ…...
Cookie、Session、JWT
目录 实现方式与原理 存储位置 安全性 应用场景 Cookie、Session 和 JWT(JSON Web Token)都是 Web 开发中用于用户身份验证和会话管理的技术,它们在实现方式、存储位置、安全性等方面存在差异: 实现方式与原理 Cookie&#…...

TPDS-2014《Efficient $k$-means++ Approximation with MapReduce》
推荐深蓝学院的《深度神经网络加速:cuDNN 与 TensorRT》,课程面向就业,细致讲解CUDA运算的理论支撑与实践,学完可以系统化掌握CUDA基础编程知识以及TensorRT实战,并且能够利用GPU开发高性能、高并发的软件系统…...

地理特征类可视化图像
目录 一、蜂窝热力地图 1. 特点 (1)优点 (2)缺点 2. 应用场景 3.python代码实现 (1)代码 (2)实现结果 二、变形地图 1. 特点 (1)优点 (2)缺点 2. 应用场景 3.python代码实现 (1)代码 (2)实现结果 三、关联地图 1. 特点 (1)优点 (2)缺点 2. 应用场景 3.pyth…...

【Java高阶面经:微服务篇】8.高可用全链路治理:第三方接口不稳定的全场景解决方案
一、第三方接口治理的核心挑战与架构设计 1.1 不稳定接口的典型特征 维度表现影响范围响应时间P99超过2秒,波动幅度大(如100ms~5s)导致前端超时,用户体验恶化错误率随机返回5xx/429,日均故障3次以上核心业务流程中断,交易失败率上升协议不一致多版本API共存,字段定义不…...

DataGridView中拖放带有图片的Excel,实现数据批量导入
1、带有DataGridView的窗体,界面如下 2、编写DataGridView支持拖放的代码 Private Sub DataGridView1_DragEnter(ByVal sender As Object, ByVal e As DragEventArgs) Handles DataGridView1.DragEnterIf e.Data.GetDataPresent(DataFormats.FileDrop) ThenDim file…...

跨域_Cross-origin resource sharing
同源是指"协议域名端口"三者相同,即便两个不同的域名指向同一个ip,也非同源 1.什么是CORS? CORS是一个W3C标准,全称是"跨域资源共享"(Cross-origin resource sharing)。它允许浏览器向跨源服务器ÿ…...

Opencv常见学习链接(待分类补充)
文章目录 1.常见学习链接 1.常见学习链接 1.Opencv中文官方文档 2.Opencv C图像处理:矩阵Mat 随机数RNG 计算耗时 鼠标事件 3.Opencv C图像处理:亮度对比度饱和度高光暖色调阴影漫画效果白平衡浮雕羽化锐化颗粒感 4.OpenCV —— 频率域滤波ÿ…...