go-redis hash slot 之旅

搭建redis 集群

  1. 创建一个网桥
docker network create -d bridge --subnet=192.168.148.0/24 --gateway=192.168.148.1 -o parent=eno1 redis-net
  1. 通过docker 文件创建redis 集群, 这里注意要不要使用redis 7以上的版本,不然会出问题
version: "3"
 
services:
  redis7001:
    image: redis:6.2.14 # 指定redis镜像,可以是name:tag/id
    container_name: redis7001 # 启动后的镜像名称,可有可无
    ports:
      - "7001:7001" # 指定对外端口
      - "17001:17001" # 指定集群端口,根据官网一般为对外端口+10000
    volumes:
      # 挂载主机中的配置文件
      - /home/duron/docker/redis_cluster/redis.conf:/conf/redis.conf
      # 将数据保存在主机上, 防止丢失
      - /home/duron/docker/redis_cluster/7001:/data
    command:
      # 默认的redis启动命令
      - "redis-server"
      # 加载指定的配置文件,这里是镜像内的路径
      - "/conf/redis.conf"
      # 对外端口号,也可以在redistribution.conf中配置
      - "--port 7001"
      # 开启redis集群模式,也可以在redistribution.conf中配置
      - "--cluster-enabled yes"
      # 集群节点配置文件名,也可以在redistribution.conf中配置
      - "--cluster-config-file nodes-7001.conf"
    networks:
      extnetwork:
        ipv4_address: 192.168.148.71 # 向桥接网络申请ip地址
 
  redis7002:
    image: redis:6.2.14
    container_name: redis7002
    ports:
      - "7002:7002"
      - "17002:17002"
    volumes:
      - /home/duron/docker/redis_cluster/redis.conf:/conf/redis.conf
      - /home/duron/docker/redis_cluster/7002:/data
    command:
      - "redis-server"
      - "/conf/redis.conf"
      - "--port 7002"
      - "--cluster-enabled yes"
      - "--cluster-config-file nodes-7002.conf"
    networks:
      extnetwork:
        ipv4_address: 192.168.148.72
 
  redis7003:
    image: redis:6.2.14
    container_name: redis7003
    ports:
      - "7003:7003"
      - "17003:17003"
    volumes:
      - /home/duron/docker/redis_cluster/redis.conf:/conf/redis.conf
      - /home/duron/docker/redis_cluster/7003:/data
    command:
      - "redis-server"
      - "/conf/redis.conf"
      - "--port 7003"
      - "--cluster-enabled yes"
      - "--cluster-config-file nodes-7003.conf"
    networks:
      extnetwork:
        ipv4_address: 192.168.148.73
 
  redis7004:
    image: redis:6.2.14
    container_name: redis7004
    ports:
      - "7004:7004"
      - "17004:17004"
    volumes:
      - /home/duron/docker/redis_cluster/redis.conf:/conf/redis.conf
      - /home/duron/docker/redis_cluster/7004:/data
    command:
      - "redis-server"
      - "/conf/redis.conf"
      - "--port 7004"
      - "--cluster-enabled yes"
      - "--cluster-config-file nodes-7004.conf"
    networks:
      extnetwork:
        ipv4_address: 192.168.148.74
 
  redis7005:
    image: redis:6.2.14
    container_name: redis7005
    ports:
      - "7005:7005"
      - "17005:17005"
    volumes:
      - /home/duron/docker/redis_cluster/redis.conf:/conf/redis.conf
      - /home/duron/docker/redis_cluster/7005:/data
    command:
      - "redis-server"
      - "/conf/redis.conf"
      - "--port 7005"
      - "--cluster-enabled yes"
      - "--cluster-config-file nodes-7005.conf"
    networks:
      extnetwork:
        ipv4_address: 192.168.148.75
 
  redis7006:
    image: redis:6.2.14
    container_name: redis7006
    ports:
      - "7006:7006"
      - "17006:17006"
    volumes:
      - /home/duron/docker/redis_cluster/redis.conf:/conf/redis.conf
      - /home/duron/docker/redis_cluster/7006:/data
    command:
      - "redis-server"
      - "/conf/redis.conf"
      - "--port 7006"
      - "--cluster-enabled yes"
      - "--cluster-config-file nodes-7006.conf"
    networks:
      extnetwork:
        ipv4_address: 192.168.148.76
 
 
networks:
  extnetwork: # 定义外部桥接网络
    external:
      name: redis-net

什么是redis cluster的hash slot

redis的hash槽在redis集群中的作用是用来将数据分配到不同的slot,来降低单个节点的压力,来保证redis的工作效率。

redis 是如何将key分配到不同的槽里的呢

redis 是同过CRC16 算法对数据进行hash取值然后在和16384 进行去模的到的slot的结果,我们在查询/存储key的时候会更具slot去获取数据或写入数据。

为什么要分配16384个

Redis 集群使用哈希槽(hash slot)来决定一个给定的键应该被分配到哪个节点。总共有 16384 个哈希槽,这个数字是一个折中的选择。

如果哈希槽的数量太少,例如只有 100 个,那么在大规模集群中,每个节点将需要处理大量的哈希槽,这可能会导致负载分布不均。另一方面,如果哈希槽的数量太多,例如 1 亿,那么管理这些哈希槽的开销将会非常大,尤其是在节点添加或删除时。

因此,16384 是一个在分布均匀性和管理开销之间取得平衡的数字。它足够大,可以在大规模集群中实现均匀的负载分布,同时又足够小,可以在节点变动时快速重新分配哈希槽。

为什么redis hash 槽要选择CRC16算法

  1. 计算速度快:CRC16 是一种非常简单的算法,计算速度非常快。这对于 Redis 这种需要处理大量键值对的数据库系统来说非常重要。

  2. 分布均匀:虽然 CRC16 是一种简单的算法,但它生成的哈希值在 0 到 16383 之间的分布是相当均匀的。这意味着键值对在 Redis 集群的各个节点之间的分布也会比较均匀。

redis 是如何获取slot的

1.) 在我们进行查询和写入操作的时候,代码在构建玩cmd的时候我们就进入了process函数,该函数的第一步就是先获取slot,红框中的代码就是获取到hash槽中的slot的值
在这里插入图片描述
2.)我们进入到cmdSlot 函数里面我们就会发现,我们马上要开始获取slot了,在进入cmdFirstKeyPos获取到pos值以后我们就可以进入slot函数获取hash slot的值了(keyPos 字段是用来帮助 go-redis 库正确地处理 Redis 集群的一个重要字段。)
在这里插入图片描述
3.)我们从这里就看到了hash slot的算法了,他正如我说的那样通过crc16算出hash值和16384 进行取模来获取我们需要通过那个slot来获取/写入数据
在这里插入图片描述

获取到slot后我们如何获取连接呢?

1.) 我们通过代码可以看到在获取到slot后,我们会进入一个cmdNode的一个函数里面,我们就是通过slot值在这个函数里面获取到node 节点的。
在这里插入图片描述
2.)我们进入cmdNode 可以看出来,这个函数给我们做了读写分离,因为我们没有开启读写分离,所以我们默认会进入slotMasterNode里面
在这里插入图片描述
3.) 我们进入这个函数可以看到,我们通过sloaNodes来获取slot 如果nodes获取失败 = 0的情况下 我们默认走了random模式 默认随机了
在这里插入图片描述
4. )该函数我们可以看出来,这个函数判断了我们的slot是否在这些nodes 里面,如果在并获取这个节点的节点信息。
在这里插入图片描述

注意:

以上代码是在"github.com/redis/go-redis/v9" v9版本的支持下进行的,如果我们使用的是v6版本,我们会发现在我们进行slot 获取的时候会报错,报错会存储到firstErr的一个字段里面,这时候系统监测到该字段有错误,就会默认进行 随机获取slot的一个操作。

redis: got 7 elements in COMMAND reply, wanted 6

所以我们如果想使用hash slot 就需要升级到高一些的版本。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

详解spring6.0新特性汇总

spring6新特性汇总 part1 spring6.0新特性 spring6.0 2022年11月。新一代框架带jdk17&jakarta ee9 https://www.graalvm.org/ part2 AOP&事务 1.AOP:面向切面编程 通过预编译方式和运行期动态 代理实现程序功能的统一维护的一种技术。 使用场景: 权…

vivado 手动设置自下而上的流量并导入网表、创建较低级别的网表

手动设置自下而上的流量并导入网表 要手动运行自下而上的流,请将较低级别的网表或第三方网表实例化为黑色盒子,Vivado工具在合成完成后将黑盒子融入完整的设计中。这个以下部分描述了该过程。 重要!Vivado合成不合成或优化加密或非加密合成…

信任与创新 | 回顾通付盾的2023!

-END- 数信云,基于区块链与人工智能的数据安全应用与服务平台

ReactNative实现弧形拖动条

我们直接看效果 先看下面的使用代码 <CircularSlider5step{2}min{0}max{100}radius{100}value{30}onComplete{(changeValue: number) > this.handleEmailSbp(changeValue)}onChange{(changeValue: number) > this.handleEmailDpd(changeValue)}contentContainerStyle{…

【自动化测试】----Java的单元测试工具Junit5

目录 支持Java的最低版本为8在pom.xml添加依赖Junit提供的注解功能 断言 Assertion类提供的一些方法测试用例执行顺序 &#xff08;为了预防测试用例执行顺序错误&#xff09;参数化 &#xff08;假设登陆操作&#xff0c;用户名和密码很多&#xff0c;尽可能通过一个测试用例…

springboot+vue实现excel导出

后端 导入pom依赖 <dependency>x<groupId>cn.afterturn</groupId><artifactId>easypoi-spring-boot-starter</artifactId><version>4.2.0</version> </dependency> Entity实体类 这里以User为例&#xff0c;可按照自己实际…

【leetcode题解C++】450.删除二叉搜索树中的节点 and 669.修剪二叉搜索树 and 108.将有序数组转换为二叉搜索树

450. 删除二叉搜索树中的节点 给定一个二叉搜索树的根节点 root 和一个值 key&#xff0c;删除二叉搜索树中的 key 对应的节点&#xff0c;并保证二叉搜索树的性质不变。返回二叉搜索树&#xff08;有可能被更新&#xff09;的根节点的引用。 一般来说&#xff0c;删除节点可…

032-安全开发-JavaEE应用Servlet路由技术JDBCMybatis数据库生命周期

032-安全开发-JavaEE应用&Servlet路由技术&JDBC&Mybatis数据库&生命周期 #知识点&#xff1a; 1、JavaEE-HTTP-Servlet技术 2、JavaEE-数据库-JDBC&Mybatis 演示案例&#xff1a; ➢JavaEE-HTTP-Servlet&路由&周期 ➢JavaEE-数据库-JDBC&Mybat…

SDL库的下载与配置(Visual Studio )2024/2/4更新

一.SDL的下载 下载链接 二.SDL的环境配置 解压以后放在中文路径下 不会添加环境变量自行搜索&#xff08;比较简单网上教程很多&#xff09; 下面进行编译器的配置 复制这段内容 x64\SDL2main.lib x64\SDL2.lib将这段代码放进去运行一下 #include <SDL.h>int main(int…

职业性格测试在求职应聘跳槽中的应用

人的性格总是千奇百怪&#xff0c;有的人总是想迎接挑战&#xff0c;超越自己&#xff0c;不停的奔着高处走&#xff0c;然而有的人总是喜欢随遇而安&#xff0c;踏踏实实一辈子&#xff0c;有份安稳的工作&#xff0c;有吃有喝就好。那么对于哪些喜欢迎接挑战&#xff0c;但又…

算法学习——华为机考题库10(HJ64 - HJ67)

算法学习——华为机考题库10&#xff08;HJ64 - HJ70&#xff09; HJ64 MP3光标位置 描述 MP3 Player因为屏幕较小&#xff0c;显示歌曲列表的时候每屏只能显示几首歌曲&#xff0c;用户要通过上下键才能浏览所有的歌曲。为了简化处理&#xff0c;假设每屏只能显示4首歌曲&a…

挑战杯 python 机器视觉 车牌识别 - opencv 深度学习 机器学习

1 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; 基于python 机器视觉 的车牌识别系统 &#x1f947;学长这里给一个题目综合评分(每项满分5分) 难度系数&#xff1a;3分工作量&#xff1a;3分创新点&#xff1a;3分 &#x1f9ff; 更多资…

LLaVA:GPT-4V(ision) 的新开源替代品

LLaVA&#xff1a;GPT-4V(ision) 的新开源替代品。 LLaVA &#xff08;https://llava-vl.github.io/&#xff0c;是 Large Language 和Visual A ssistant的缩写&#xff09;。它是一种很有前景的开源生成式 AI 模型&#xff0c;它复制了 OpenAI GPT-4 在与图像对话方面的一些功…

SpringCloud-生产者和消费者

一、生产者和消费者的定义 在 Spring Cloud 中&#xff0c;术语 "生产者" 和 "消费者" 用于描述微服务架构中的两种基本角色。 角色定义生产者 Provider生产者是提供具体服务或功能的模块。它将业务逻辑封装成服务&#xff0c;供其他模块调用。生产者向服…

如何构建多种系统架构支持的 Docker 镜像

如何构建多种系统架构支持的 Docker 镜像 1.概述2.解决方案3.使用manifest案例 1.概述 我们知道使用镜像创建一个容器&#xff0c;该镜像必须与 Docker 宿主机系统架构一致&#xff0c;例如 Linux x86_64 架构的系统中只能使用 Linux x86_64 的镜像创建容器 例如我们在 Linux…

python Flask 写一个简易的 web 端上传文件程序 (附demo)

python Flask 写一个简易的 web 端上传文件程序 &#xff08;附demo&#xff09; 需求介绍核心代码&#xff1a; 文件结构前端文件后端文件 完整代码演示 需求 在当今数字化时代&#xff0c;文件上传需求日益普遍。无论是个人还是企业&#xff0c;都可能需要实现文件上传功能。…

商业智能(BI)数据分析、挖掘概念

商业智能&#xff08;BI&#xff09;数据分析挖掘概念 一、商业智能&#xff08;BI&#xff09;数据分析挖掘概念 数据挖掘目前在各类企业和机构中蓬勃发展。因此我们制作了一份此领域常见术语总结。 1.分析型客户关系管理&#xff08;Analytical CRM/aCRM 用于支持决策&…

MySQL集群 1主1从 主从复制(原理 及配置命令)

CSDN 成就一亿技术人&#xff01; 今天分享一期 MySQL集群方案&#xff1a;主从集群 也是最常用的一种 CSDN 成就一亿技术人&#xff01; 目录 使用主从复制的原因&#xff08;优点&#xff09; 主从复制的过程&#xff08;原理&#xff09; 了解两大线程&#xff08; I/O…

day 19 (进阶)

一 首先 昨日内容回顾 思维导图&#xff1a;&#xff08;日更附 养成习惯 加油&#xff09; 补充Linux思维导图 衔接一下之前学过的 二 课堂知识提炼 练习&#xff1a;统计文件行数 想查看是否正确就用 grep -c “文件名” 来看 会输出结果 练习&#xff1a;把file.c里面的…

数据包跟踪器-实施 DHCPv4

实验大纲 第 1 部分&#xff1a;把路由器配置为 DHCP 服务器 步骤 1&#xff1a;配置要排除在外的 IPv4 地址 步骤 2&#xff1a;在 R2 上 给 R1 LAN 创建一个 DHCP 池 步骤 3&#xff1a;在 R2 上 给 R3 LAN 创建一个 DHCP 池 第 2 部分&#xff1a;配置 DHCP 中继 步骤…
最新文章