redis相关知识——一致性哈希、哈希槽

1、集群分片模式

如果 redis 只用复制功能做主从,那么当数据量巨大的情况下,单机情况下可能已经承受不下一份数据,更不用说是主从都要各自保存一份完整的数据。在这种情况下,数据分片是一个非常好的解决办法。

redis 的 custer 正是用于解决该问题。它主要提供两个功能:

1、自动对数据分片,落到各个节点上
2、即使集群部分节点失效或者连接不上,依然可以继续处理命令

对于第二点,它的功能有点类似于 sentienl 的故障转移,在这里不细说。下面详细了解下 redis 的槽位分片原理,在此之前,先了解下分布式简单哈希算法和一致性哈希算法,以帮助理解槽位的作用。

2、简单哈希算法

假设有三台机,数据落在哪台机的算法为:

c = Hash(key) % 3

例如 key A 的哈希值为4,4 % 3 = 1,则落在第二台机。Key ABC 哈希值为11,11 % 3 = 2,则落在第三台机上。

利用这样的算法,假设现在数据量太大了,需要增加一台机器。A 原本落在第二台上,现在根据算法4 % 4 = 0,落到了第一台机器上了,但是第一台机器上根本没有 A 的值。这样的算法会导致增加机器或减少机器的时候,引起大量的缓存穿透,造成雪崩

3、一致性哈希算法

在1997年,麻省理工学院的 Karger 等人提出了一致性哈希算法,为的就是解决分布式缓存的问题。

在一致性哈希算法中,整个哈希空间是一个虚拟圆环。从 0 ~ 2^32-1 代表的分别是一个个的节点,这个环也叫哈希环。
在这里插入图片描述
假设有四个节点 Node D0,D1,D2,D3,经过 ip 地址的哈希计算,它们的位置如下:
在这里插入图片描述
然后就是需要通过数据 key 找到对应的服务器然后存储了,我们约定,通过数据 key 的哈希值落在哈希环上的节点,如果命中了机器节点就落在这个机器上,否则落在顺时针直到碰到第一个机器。如下图所示 : A 的哈希值落在了 D2 节点的前面,往下找落在了 D2 机器上,D的哈希值 在 D1 节点的前面,往下找到了 D1 机器,B的哈希值刚好落在了D1 节点上,依次~~~

解决问题
一致性哈希主要就是解决当机器减少或增加的时候,大面积的数据重新哈希的问题,主要从下面 2 个方向去考虑的,

  • 当节点宕机时,该节点的数据记录会被定位到下一个节点上,其它的数据都没有被影响到
  • 当新增节点的时候 ,相关区间内的数据记录就需要重新哈希,其他位置的数据不需要改变

4.1 一致性哈希导致的数据倾斜问题

一致性Hash算法在服务节点太少时,容易因为节点分部不均匀而造成数据倾斜(被缓存的对象大部分集中缓存在某一台服务器上)问题。比如只有 2 台机器,这 2 台机器离的很近,那么顺时针第一个机器节点上将存在大量的数据,第二个机器节点上数据会很少。如下图所示,D0 机器承载了绝大多数的数据

在这里插入图片描述

4.2虚拟节点解决数据倾斜问题

为了避免出现数据倾斜问题,一致性 Hash 算法引入了虚拟节点的机制,也就是每个机器节点会进行多次哈希,最终每个机器节点在哈希环上会有多个虚拟节点存在,使用这种方式来大大削弱甚至避免数据倾斜问题。同时数据定位算法不变,只是多了一步虚拟节点到实际节点的映射,例如定位到“D1#1”、“D1#2”、“D1#3”三个虚拟节点的数据均定位到 D1 上。这样就解决了服务节点少时数据倾斜的问题。在实际应用中,通常将虚拟节点数设置为32甚至更大,因此即使很少的服务节点也能做到相对均匀的数据分布。这也是 Dubbo 负载均衡中有一种一致性哈希负载均衡的实现思想。

在这里插入图片描述

5 哈希槽

redis 集群(cluster)并没有选用上面一致性哈希,而是采用了**哈希槽(slot)**的这种概念。主要的原因就是上面所说的,一致性哈希算法对于数据分布、节点位置的控制并不是很友好。

首先哈希槽其实是两个概念,第一个是哈希算法。redis cluster 的 hash 算法不是简单的 hash(),而是 crc16 算法,一种校验算法。另外一个就是槽位的概念,空间分配的规则。其实哈希槽的本质和一致性哈希算法非常相似,不同点就是对于哈希空间的定义。一致性哈希的空间是一个圆环,节点分布是基于圆环的,无法很好的控制数据分布。而 redis cluster 的槽位空间是自定义分配的,类似于 windows 盘分区的概念。这种分区是可以自定义大小,自定义位置的。

  • redis cluster 包含了16384个哈希槽,每个 key 通过计算–CRC-16(key)%16384– 的值后属于哪一个槽位上,而这个槽位是属于哪个存储节点的,则由用户自己定义分配
  • 例如机器硬盘小的,可以分配少一点槽位,硬盘大的可以分配多一点。如果节点硬盘都差不多则可以平均分配。所以哈希槽这种概念很好地解决了一致性哈希的弊端。
  • 每个槽能存放多少数据需要根据redis的内存和key的大小来判断,比如redis为4G内存,则每个槽能存放的容量就是4G/16384。key的定位规则是根据CRC-16(key)%16384的值来判断属于哪个槽。出处见此处

另外在容错性和扩展性上,表象与一致性哈希一样,都是对受影响的数据进行转移。而哈希槽本质上是对槽位的转移,把故障节点负责的槽位转移到其他正常的节点上。扩展节点也是一样,把其他节点上的槽位转移到新的节点上。

但一定要注意的是,对于槽位的转移和分派,redis 集群是不会自动进行的,而是需要人工配置的。所以 redis 集群的高可用是依赖于节点的主从复制与主从间的自动故障转移。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值