一致性hash主要用于分布式系统中,用于解决数据选择节点存储、选择节点访问、增删节点后数据的迁移和重分布问题。redis集群并没有使用一致性hash,而是使用了hash槽来解决数据分配的问题。

一致性hash:

它是一个0-2^32次方的圆,主要操作步骤:将每一个服务节点进行hash(如ip),让其落在这个闭合的圆环上;当我们进行数据存储或访问时,计算key的hash值,让其也落在这个闭合圆环之中;那么它顺时针找到的第一个服务节点就是处理key的节点

当添加节点时,例如再节点2和4之间添加了一个节点5,那么就有可能伴随数据的重分配,图中黄色区域的数据被分配到了节点5之上

当删除节点时,那么它的数据就会被分配到它顺时针寻找到的下一个节点之上。以下图为例节点2被删除,2的数据被分配到了4,那么就有可能出现一个问题,4的访问量或内存使用率就会瞬间增高,如果2之上有热点数据,就有可能将4直接打挂,这样就会顺延再将数据转移到3,从而导致所有节点循环崩溃。

同时当集群中节点过少时还有可能出现数据倾斜,大量的数据都被分配到了同一个节点上,导致单一节点内存使用率和qps都很高,分布式服务的负载不平衡。如下图所示,从A顺时针到B明显比B顺时针到A所占的区域小,那么数据被分配到A的概率就会比B大。

为了解决循环崩溃现象和数据倾斜现象,提出了虚拟节点的概念。就是将真实节点计算多个哈希形成多个虚拟节点并放置到哈希环上,定位算法不变,只是多了一步虚拟节点到真实节点映射的过程。如下图所示每个节点都映射出了两个虚拟节点,当节点1挂掉以后,它的数据并没有全部转移到同一个节点,而是被分配到了v301和v200,即节点2和3之上;此外由于加入了虚拟节点数据倾斜的问题也得到了解决。

redis 使用数据分片的hash槽来应对数据存储和读取。redis集群共有2^14次方16384个hash槽,当操作数据时,使用CRC16算法计算key的hash值,然后与16384取模从而确定该数据是属于哪一个slot槽的。redis集群中,每个服务节点都被分配一段hash槽,只要确定了数据属于哪一个槽,就可以确定该数据是在哪一个节点之上。槽是可以迁移的,master节点的slave节点不分配槽,只拥有读权限即使用权。但是注意在代码中redis cluster执行读写操作的都是master节点,并不是你想 的读是从节点,写是主节点(不过应该可以进行设置,从节点也提供读的能力,因为MT的Squirrel从节点可以提供读能力)。第一次新建redis cluster时,16384个槽是被master节点均匀分布的。当新增或删除master节点时,需要对槽进行重分配,而不是直接对数据进行分配。对于hash槽的转移和分配,redis不会自动进行,需要人工辅助。

一致性hash和redis hash槽的区别

1. redis hash槽并不是闭合的,它一共有16384个槽,使用CRC16算法计算key的hash值,与16384取模,确定数据在哪个槽中,从而找到所属的redis节点;一致性hash表示一个0到2^32的圆环,对数据计算hash后落到该圆环中,顺时针第一个节点为其所属服务。

2.一致性hash是通过虚拟节点去避免服务节点宕机后数据转移造成的服务访问量激增、内存占用率过高、数据倾斜等问题,保证数据完整性和集群可用性的;而hash集群是使用主从节点的形式,主节点提供读写服务,从节点进行数据同步备份,当主节点出现故障后,从节点继续提供服务。

二、redis集群中数据迁移

当向集群中添加节点后,新添加的节点中是没有分配槽的,假设我们新在集群中添加了节点D,那么可以将现有节点(A、B、C)的slot分配给新节点。例如从A分配slot8至D,那么在槽迁移的中间状态下slot8在A表现为MIGRATING、在D表现为IMPORTING。

当槽迁移的过程中,发生了key属于该槽的请求即当客户端请求的key处于在正在迁移的某个slot时,因为此时节点的映射关系(即槽与节点的映射)还没有改变,客户端依然认为slot8是属于A的,但是其中的一些key所对应的数据可能已经被转移到了D,对于A来说会有如下几种情况:

(1)key还在A,那么进行处理后返回

(2)key不在A了,返回ASK,让其发送ASKING命令到目标节点即D,然后进行请求

(3)如果命令包括了多个key,如果这些key都存在则进行操作后返回;如果都不存在返回客户端ASK;如果部分存在,则返回客户端TRYAGAIN,通知客户端稍后重试,这样当所有的key都迁移完成后再请求就会返回ASK

如果请求了目标节点的IMPORTING状态的slot,会出现以下几种情况

(1)如果是正常的请求则会发送MOVED命令,此时说明节点映射出错了,迁移还没有完成,被slot还属于源节点,会刷新映射

(2)如果是ASKING命令则会被执行,key存在,执行操作后返回;key不存在,则会被新建

键空间迁移

在槽迁移的前提下,还会进行键迁移,即将节点A中槽8对应键空间迁移至节点D。执行migrate命令,分为三步完成该过程,即dump(A)、restore(D)、del(A)

完成之后会将处于migrating和importing状态的槽置为正常状态,同时会刷新槽与节点的映射关系

在redis代码表示节点node的结构体ClusterNode中,存在一个char类型的slots数组和一个int型numSlots,数组长度是2048,表示一个二进制位数组,包含16384个二进制位,每一位默认为0,如果一个slot属于该节点,那么它在数组中对应下标所在的二进制位就会变成1;numslots表示该节点拥有多少个槽。

而槽的分配信息存储在clusterState结构体的clusterNode类型的数组中,它的长度为16384,即我们通过CRC16算法得出key的hash值,并对16384取模后使用该值对应的slot是哪一个,获取数组对应下标的元素,它就是该槽所属的redis节点。

redis集器并不会使用代理,当一个操作请求来到了节点a,但是经过计算发现key对应的槽不在a上,那么此时a会执行move命令将它转发到正确的节点上

Redis Cluster 分区实现原理 - _1900 - 博客园

redis:ASK错误和MOVED错误区别_machitaoX的博客-CSDN博客_ask错误

对话张冬洪 | 全面解读NoSQL数据库Redis的核心技术与应用实践_数据和云的博客-CSDN博客

一致性hash和redis中hash槽的区别相关推荐

  1. redis 中 Hash哈希介绍 及常用命令 (附有示例)

    目录 一.Redis中Hash介绍 二.常用命令 三.示例 hset hget hmset   .. hexists hkeys hvals hincrbu hsetnx 四.redis中Hash底层 ...

  2. redis中hash类型介绍

    在redis中,hash数据类型存储的数据与mysql数据库中存储一条记录极为相似,是一个string类型的field和value的映射表,它特别适合用于存储对象,但字段值只能是字符串,不支持其他类型 ...

  3. redis中hash数据结构

    目录 hash的数据结构 ziplist底层实现 字典 底层实现 扩容 缩容 引用 hash的数据结构 hash底层数据结构的实现包括两种:ziplist和字典 当保存的所有键值对字符串长度小于 64 ...

  4. mysql的hash分区_MySQL中hash和key分区值的计算方法

    MySQL中hash和key分区值的计算方法 mysql中有一种叫作key作为partition key的类型.来看看记录是怎么分布的 对于hash 分区,使用%操作符,每个partition key ...

  5. redis中multi和pipeline区别以及效率(推荐使用pipeline)

    手册得知 pipeline 只是把多个redis指令一起发出去,redis并没有保证这些指定的执行是原子的:multi相当于一个redis的transaction的,保证整个操作的原子性,避免由于中途 ...

  6. Redis中jedis与lettuce区别

    1.Jedis 优点: 提供了比较全面的 Redis 操作特性的 API API 基本与 Redis 的指令一一对应,使用简单易理解 缺点: 同步阻塞 IO 不支持异步 是基于tcp的阻塞式连接方式 ...

  7. redis的zset的底层实现_Redis中hash、set、zset有多牛?从底层告诉你数据结构原理...

    前言 今天来说下Redis中hash.set.zset的底层数据结构原理! Redis-哈希对象(hash) hash的底层存储有两种数据结构,一种是ziplist,另外一种是hashtable,这两 ...

  8. set列表对象去重_Redis中hash、set、zset有多牛?从底层告诉你数据结构原理

    前言 今天来说下Redis中hash.set.zset的底层数据结构原理! Redis-哈希对象(hash) hash的底层存储有两种数据结构,一种是ziplist,另外一种是hashtable,这两 ...

  9. Redis 的 hash,及其序列化问题

    Redis 的 hash,及其序列化问题 介绍 常用命令 应用场景 hash的序列化存储方式 介绍 一次应用中,需要将MySQL中的表在redis中缓存一份,防止查询次数太多,对数据库造成压力.用到了 ...

最新文章

  1. 心中无码,自然高清 | 联合去马赛克与超分辨率研究论文Pytorch复现
  2. CVPR 2018 RASNet:《Learning Attentions: Residual Attentional Siamese Network for Tracking》论文笔记
  3. 拆分文件_领导让把工作表拆分每个文件,我花半个小时,同事1分钟搞定了
  4. LeetCode Algorithm 746. 使用最小花费爬楼梯
  5. MFC和Win32之三___CGdiObject类和windows Gdi对象
  6. #define 喵 int_【Angew. Chem. Int. Ed.】具多样化不对称反应性的三氮唑芳基碘化物
  7. java四个基本步骤_javac编译的四个主要的流程
  8. QT.pro工程文件中判断宏定义是否存在
  9. (转)MapReduce中的两表join几种方案简介
  10. STL之priority_queue 感觉讲的不错!!!呵呵
  11. 软件如何实现屏幕共享?
  12. 对AD采样信号的简单滤波处理
  13. 【大牛感悟】淘宝陈吉平职业生涯--敬不甘平凡的自己
  14. 如何下载哔哩哔哩(bilibili)网页端视频
  15. matplotlib 配色之内置 colormap
  16. 如何自己编写一个交通仿真软件(一)火种。
  17. 视频教程-Python编程的术与道:Python语言入门-Python
  18. 优秀网页设计的七条基本准则
  19. 苹果新专利将 Siri 融入 iMessage,会侵犯到用户的隐私吗?
  20. mysql授权连接_MySQL 连接认证授权步骤

热门文章

  1. no suitable image found解决办法
  2. chapter1 静态分析技术-01反病毒引擎扫描virustotal
  3. BIM在设计、施工和运维的细分应用点(中英文对照)
  4. 为了父母形婚值不值?
  5. 获取iframe src里的参数
  6. linux没有浏览器如何卸载,在Ubuntu 20.04系统上安装及卸载Tor浏览器的方法
  7. CSM5733SE与AP2125K-33TRG1参数对比测试
  8. win环境nginx下载安装和基本操作使用解析
  9. linux 测试程序性能,linux 压力测试性能IO MEM CPU
  10. 如何提高跨境店铺的权重—扬帆凌远