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/idcontainer_name: redis7001 # 启动后的镜像名称,可有可无ports:- "7001:7001" # 指定对外端口- "17001:17001" # 指定集群端口,根据官网一般为对外端口+10000volumes:# 挂载主机中的配置文件- /home/duron/docker/redis_cluster/redis.conf:/conf/redis.conf# 将数据保存在主机上, 防止丢失- /home/duron/docker/redis_cluster/7001:/datacommand:# 默认的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.14container_name: redis7002ports:- "7002:7002"- "17002:17002"volumes:- /home/duron/docker/redis_cluster/redis.conf:/conf/redis.conf- /home/duron/docker/redis_cluster/7002:/datacommand:- "redis-server"- "/conf/redis.conf"- "--port 7002"- "--cluster-enabled yes"- "--cluster-config-file nodes-7002.conf"networks:extnetwork:ipv4_address: 192.168.148.72redis7003:image: redis:6.2.14container_name: redis7003ports:- "7003:7003"- "17003:17003"volumes:- /home/duron/docker/redis_cluster/redis.conf:/conf/redis.conf- /home/duron/docker/redis_cluster/7003:/datacommand:- "redis-server"- "/conf/redis.conf"- "--port 7003"- "--cluster-enabled yes"- "--cluster-config-file nodes-7003.conf"networks:extnetwork:ipv4_address: 192.168.148.73redis7004:image: redis:6.2.14container_name: redis7004ports:- "7004:7004"- "17004:17004"volumes:- /home/duron/docker/redis_cluster/redis.conf:/conf/redis.conf- /home/duron/docker/redis_cluster/7004:/datacommand:- "redis-server"- "/conf/redis.conf"- "--port 7004"- "--cluster-enabled yes"- "--cluster-config-file nodes-7004.conf"networks:extnetwork:ipv4_address: 192.168.148.74redis7005:image: redis:6.2.14container_name: redis7005ports:- "7005:7005"- "17005:17005"volumes:- /home/duron/docker/redis_cluster/redis.conf:/conf/redis.conf- /home/duron/docker/redis_cluster/7005:/datacommand:- "redis-server"- "/conf/redis.conf"- "--port 7005"- "--cluster-enabled yes"- "--cluster-config-file nodes-7005.conf"networks:extnetwork:ipv4_address: 192.168.148.75redis7006:image: redis:6.2.14container_name: redis7006ports:- "7006:7006"- "17006:17006"volumes:- /home/duron/docker/redis_cluster/redis.conf:/conf/redis.conf- /home/duron/docker/redis_cluster/7006:/datacommand:- "redis-server"- "/conf/redis.conf"- "--port 7006"- "--cluster-enabled yes"- "--cluster-config-file nodes-7006.conf"networks:extnetwork:ipv4_address: 192.168.148.76networks: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.mzph.cn/news/667711.shtml

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

相关文章

Tomcat组件架构与数据流

一、背景与简介 Tomcat我们都知道是一个开源的、实现了大部分Java EE、Servlet、JSP规范的Servlet容器, 允许我们将实现了Serlvet接口的Web程序war包进行部署运行。 但是你有对Tomcat做过细致的学习么? 我相信大部分同学和我一样,之前也是只会进行简单使用&#x…

django线上教育学习平台大数据分析系统python

随着互联网技术不断地发展,网络与大数据成为了人们生活的一部分,而线上教育平台大数据分析作为网上应用的一个全新的体现,由于其特有的便捷性,已经被人们所接受。目前主流的线上教育平台大数据分析服务不仅不明确并且管理盈利较低…

解析Go内存逃逸

Go语言以其内建的垃圾回收机制和内存安全性而著称。然而,在编写Go代码时,我们仍然需要关注内存的分配和释放,以确保程序的性能和稳定性。接下来将深入讨论Go中的内存逃逸现象,探讨其原因、优化策略,以及在实际开发中的…

NLP任务之Named Entity Recognition

深度学习的实现方法: 双向长短期记忆网络(BiLSTM): BiLSTM是一种循环神经网络(RNN)的变体,能够捕捉序列数据中的长期依赖关系。在NER任务中,BiLSTM能有效地处理文本序列,捕捉前后文本…

专业课130+总分420+南京大学851信号与系统考研经验南大电子信息与通信系统

经过一年的复习,顺利上岸,被南京大学录取,今年专业课130,总分420,回忆这一年的复习还是有很多经验分享,希望对大家复习有帮助。 专业课: 南京大学851信号与系统难度这几年无论是范围还是难度都…

【MySQL】学习并使用DQL实现排序查询和分页查询

🌈个人主页: Aileen_0v0 🔥热门专栏: 华为鸿蒙系统学习|计算机网络|数据结构与算法 ​💫个人格言:“没有罗马,那就自己创造罗马~” #mermaid-svg-SP91zTA41FlGU0Ce {font-family:"trebuchet ms",verdana,arial,sans-serif;font-siz…

计算机服务器中了DevicData勒索病毒如何解密,DevicData勒索病毒解密流程

网络数据安全一直是企业关心的主要话题,近期,云天数据恢复中心接到很多企业的求助,企业的计算机服务器遭到了DevicData勒索病毒攻击,导致企业计算机服务器瘫痪无法正常工作,严重影响了工作业务开展。经过云天数据恢复中…

软件架构风格:您的系统设计指南

软件架构风格:您的系统设计指南 软件架构不仅仅是组织代码的方式,它是对软件整体结构和行为的全面规划。一个好的架构能够让软件更加灵活、可维护,并且能够应对未来的变化。下面是一些流行的软件架构风格,以及它们的C#代码例子&a…

docker-compose常用命令全集

1、启动或构建应用程序: docker-compose up 根据 docker-compose.yml 文件中定义的配置启动应用程序的服务。如果镜像不存在,将会构建镜像 2、后台启动应用程序: docker-compose up -d 在后台模式下启动应用程序的服务,不会在…

【算法刷题】前K个高频单词

给定一个单词列表 words 和一个整数 k ,返回前 k 个出现次数最多的单词。 返回的答案应该按单词出现频率由高到低排序。如果不同的单词有相同出现频率, 按字典顺序 排序。 示例 1: 输入: words [“i”, “love”, “leetcode”, “i”, “l…

Flask 项目自动生成 API 文档的高效实践

Flasgger,作为一款强大的 Flask 扩展,自动从 Flask 应用中提取并生成 OpenAPI 规范文档,配备 SwaggerUI,为开发者提供了一条快捷通道,让 API 的文档编制和交互式测试变得简单易行。Flasgger 的设计原则是简化开发流程&…

【已解决】c++ qt选中该行为什么该列部分变色

笔者开启了QTableView中交替行改变颜色,发现笔者自定义绘制的水平滚动条,在选中后不发生颜色改变,这让笔者很疑惑。笔者查阅资料后发现,自定义绘制的控件,要自身设置颜色。当笔者解决了这个问题时,顺手就将…

flutter 操作mysql

引入模块 dependencies: flutter: sdk: flutter mysql1: ^0.20.0 mysql helper 的代码 import dart:async; import package:mysql1/mysql1.dart; class MySqlHelper { static const _host localhost; static const _port 3333; static const _user user; static c…

6.0 MapReduce 服务使用教程

在学习了之前的 MapReduce 概念之后,我们应该已经知道什么是 Map 和 Reduce,并了解了他们的工作方式。 本章将学习如何使用 MapReduce。 Word Count Word Count 就是"词语统计",这是 MapReduce 工作程序中最经典的一种。它的主要…

PyTorch中的nn.Embedding的使用、参数及案例

PyTorch中的nn.Embedding的使用 Embedding层在神经网络中主要起到降维或升维的作用。具体来说,它通过将输入(通常是离散的、不连续的数据,如单词或类别)映射到连续的向量空间,从而实现数据的降维或升维。 在降维方面&…

【SAR成像】基于RD、CS和ωk算法的合成孔径雷达成像算法原理与实现

基于RD、CS和ωk算法的合成孔径雷达成像算法实现 前言SAR基本概念雷达获取数据的几何关系低斜视角下的回波信号模型 RADARSAT-1主要参数数据预处理数据读取与再封装数据补零 成像算法坐标轴的产生RD算法距离压缩距离徙动矫正方位压缩 CS算法第一次相位相乘 变标后的信号第二次相…

Qt应用软件【协议篇】http协议get、post示例

文章目录 QT Http的APIHTTP GET 请求示例HTTP POST 请求示例伪装chrome浏览器get请求 QT Http的API QNetworkAccessManager 作用:管理所有的网络请求,是发送请求和接收响应的中心点。主要功能: 发送HTTP请求(GET, POST, PUT, DE…

基于若依的ruoyi-nbcio流程管理系统自定义业务实现一种简单的动态任务标题需求

更多ruoyi-nbcio功能请看演示系统 gitee源代码地址 前后端代码: https://gitee.com/nbacheng/ruoyi-nbcio 演示地址:RuoYi-Nbcio后台管理系统 更多nbcio-boot功能请看演示系统 gitee源代码地址 后端代码: https://gitee.com/nbacheng/n…

[Android] 240204批量生成联系人,短信,通话记录的APK

平常在做测试的时候,需要批量生成很多测试数据; 陌生人 联系人名字的生成支持随机生成,也可以自定义生成,自定义生成陌生人的数据,联系人的名字是否带索引; 通话记录 随机生成通话记录,在生…

云数据库RDS云监控

1. 什么是云数据库RDS?它有哪些特点? 云数据库RDS是一种在线关系型数据库服务,它具备的特点包括: 安全可靠:提供了容灾、备份、恢复等高可用性功能,确保数据的安全与可靠。弹性伸缩:用户可以根…