【Redis】Redis的数据分布算法

本文介绍了哈希算法、一致性哈希、带有限负载一致性哈希、虚拟节点一致性哈希以及虚拟槽分区这五种算法,着重讨论了它们在解决数据分布、扩展性和性能差异等问题上的应用和优缺点。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一共有五种算法,分别为:哈希算法、一致性哈希算法、带有限负载的一致性哈希算法、虚拟节点一致性哈希算法、虚拟槽分区

哈希算法

思想:根据某个key的值或者key 的哈希值与当前可用的 master 节点数取模,根据取模的值获取具体的服务器
缺点:扩展性非常差。万一某个节点宕机,就需要重新计算

一致性哈希算法

目的:为了解决哈希算法可扩展性差的问题
思想:数据映射到哈希环上后按照顺时针的方向查找存储节点,即从数据映射在环上的位置开始,顺时针方向找到的第一个存储节点,那么他就存储在这个节点上
图解
在这里插入图片描述
上图所示:id=2会存储在server2,id=3,1,5,6会存储在server3,id=4会存储在server1
缺点:会出现数据分布不均匀的问题,也就是数据倾斜的问题。但是在一定程度上可扩展性更强

带有限负载的一致性哈希算法

目的:为了解决数据倾斜的问题
思想:给每个存储节点设置一个存储上限值来控制存储节点添加或移除造成的数据不均匀,当数据按照一致性哈希算法找到相应的存储节点时,要先判断该存储节点是否达到了存储上限;如果已经达到了上限,则需要继续寻找该存储节点顺时针方向之后的节点进行存储
图解
在这里插入图片描述
我们的添加顺序按照 id 大小排序,所以前四个数据(1,2,3,4)都没有问题,这时候的服务器都没有超过最高负载数量。
id=5 的数据落在了服务器 server2 和服务器 server3 之间,本应该是存储在服务器server3 上,但是由于此时的服务器 server3 上已经存储了 id=1、id=3 的数据,达到了最高限定,因此 id=5 的数据会沿着顺时针的方向继续往下寻找服务器。下一个服务器就是 server1,此时的服务器 server1 只存储了 id=4 的数据,并没有达到上限,所以 id=5 的数据就会存储在服务器 server1。id=6 的数据同样的道理,存储在server2上面。

虚拟节点一致性哈希算法

目的:带有限负载的一致性哈希算法存在一个服务器之间异构性(每台服务器的性能配置可能存在不一样)的问题
思想:根据每个节点的性能为每个节点划分不同数量的虚拟节点,并将这些虚拟节点映射到哈希环中,然后再按照一致性哈希算法进行数据映射和存储
图解
在这里插入图片描述
假设服务器server3是配置最差的,所以我们以服务器server3 为基准,服务器server2 是服务器server3 的两倍,服务器server1 是服务器server3 的三倍,我们建立虚拟节点。
假设服务器server3 的虚拟节点为服务器server3_1,服务器server2 就有两个虚拟节点服务器server2_1、服务器server2_2,服务器server1 有三个虚拟节点服务器server1_1、服务器server1_2、服务器server1_3。
落到虚拟节点上的数据都会存到对应的物理服务器上,所以通过带虚拟节点的一致性哈希算法后,数据存储结果为:数据id=2、id=3、id=5 的数据都会存储到服务器server1 上,id=1 的数据将会存储到服务器server2 上,数据 id=4、id=6 都会存放到服务器server3上。

虚拟槽分区

虚拟槽分区是 redis cluster 中默认的数据分布技术。
Redis cluster 中有16384(0~16383)个槽,会将这些槽平均分配到每个 master 上,在存储数据时利用 CRC16 算法,具体的计算公式为:slot = CRC16(key)/16384 来计算 key 属于哪个槽。
一个key查找过程图示如下:
在这里插入图片描述
虚拟槽分区解耦了数据与节点的关系,通过引入槽,让槽成为集群内数据管理和迁移的基本单位,简化了节点扩容和收缩难度。我们只需关注数据在哪个槽,所以虚拟槽分区可以说比较好的兼容了数据均匀分布和扩展性的问题

### Redis集群中的哈希槽算法数据分布机制 #### 哈希槽的概念及其作用 Redis集群利用哈希槽(Hash Slot)机制来管理键值对的分布式存储。整个数据空间被划分为16384个哈希槽,每个键通过CRC16算法计算其哈希值,并对该数值除以16384取模得到具体的哈希槽数字[^1]。 #### 键到哈希槽的映射过程 当一个新键加入时,系统会先基于该键的内容计算出唯一的哈希码;接着再用这个哈希码去除以总的哈希槽数量——即16384,从而获得最终对应的哈希槽编号。此方法确保了即使是在大规模环境下也能高效地定位特定键所在位置。 ```python def get_hash_slot(key): import crc16 # 计算crc16校验和并转换成整型 hash_value = int(crc16.crc16xmodem(bytes(key, 'utf-8'))) # 对总槽数求余获取具体槽位 slot_number = hash_value % 16384 return slot_number ``` #### 解决传统哈希取余法存在的局限性 相比于简单的`hash(key)%N`方式,在面对节点数量变动时会出现严重的性能下降甚至完全失效的情况,因为这会导致大量已有的键重新分配给不同的节点,进而引发所谓的“全网风暴”。而采用固定的哈希槽数目则有效规避了此类风险,使得即便有新的实例加入或旧实例退出也不会影响其他成员的工作状态[^3]。 #### 应对潜在的数据倾斜现象 尽管如此,如果某些热点区域内的哈希槽承载过多请求,则仍可能出现局部过载的情形。为此,可以通过调整各物理节点所负责的具体范围以及引入虚拟节点等方式加以缓解,保证整体资源利用率更加合理平衡[^2]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值