Redis集群里用一致性哈希来分片,感觉挺关键但也有点复杂和讲究
- 问答
- 2025-12-26 03:30:54
- 2
根据杨传辉在《大规模分布式存储系统:原理解析与架构实战》中的阐述,一致性哈希的核心目的是在分布式缓存系统(如Redis集群)中,当需要增加或减少机器节点时,能够最大限度地减少需要重新映射的数据量,从而避免大规模的数据迁移,保证系统的稳定性和扩展性。
想象一下,如果没有一致性哈希,我们用一个简单的“取模”方法来分配数据,我们有3台Redis服务器,决定一条数据存到哪台服务器的方法是用数据的键(key)的哈希值除以3,看余数是几就存到第几台服务器上,这在一开始是没问题的,当我们需要扩容,比如增加一台服务器变成4台时,问题就来了,这时,计算方法变成了哈希值除以4取余数,你会发现,绝大部分数据之前算出来的存放位置(余数)和现在算出来的都不一样了,这意味着,几乎所有的数据都需要被重新计算,然后从原来的服务器搬到新的服务器上去,这个过程叫做“数据迁移”,对于一个大集群来说,这简直是灾难性的,迁移过程中服务很可能不可用,而且对网络和磁盘的压力巨大。

一致性哈希就是为了解决这个“牵一发而动全身”的问题而生的,它的设计非常巧妙,它不再是对服务器的数量取模,而是构建一个巨大的、虚拟的“哈希环”,这个环可以想象成一个钟表的表盘,不过这个表盘的范围是从0到2的32次方减1(或者64次方,取决于实现),首尾相连形成一个环。
具体操作分两步: 第一步,把服务器节点“放”到环上,我们同样使用一个哈希函数,但这次是对服务器的唯一标识(比如IP地址或主机名)进行哈希计算,得到一个哈希值,这个哈希值必然会落在环上的某个位置,这样,我们就把几台服务器均匀地(理想情况下)分布在了这个巨大的环上。

第二步,决定数据该属于哪个节点,当有一条数据需要存储时,我们计算这条数据的键(key)的哈希值,这个值也会落在环上的某个点,我们从数据这个点开始,沿着环顺时针方向寻找,遇到的第一个服务器节点,就是这条数据应该存放的“家”。
一致性哈希的“一致性”优势体现在哪里呢?还是看扩容的例子,现在我们要加入第四台服务器,我们同样计算新服务器的哈希值,把它放到环上,这时,环被打破了,但受影响的仅仅是新节点逆时针方向到上一个节点之间的这一小段区域上的数据,原来这些数据是属于新节点的下一个节点的,现在只需要把这一小段区域的数据从原来的节点迁移到新节点上就可以了,环上其他绝大部分区域的数据,寻找顺时针方向第一个节点的结果都没有发生变化,所以它们完全不需要动,这就实现了最小化的数据迁移,删除一个节点也是同样的道理,只有被删除节点上的数据需要被重新分配到下一个节点上,其他数据不受影响。
杨传辉也指出了最基础的一致性哈希可能存在的问题:节点分布不均,如果服务器节点数量很少,它们哈希后可能在这个巨大的环上分布得非常不均匀,导致有的节点管理的环区间很大(存储的数据多),有的很小(存储的数据少),这就造成了“数据倾斜”,负载不均衡。
为了解决这个问题,又引入了“虚拟节点”的概念,虚拟节点是说,我们不再让一个物理服务器节点只对应环上的一个点,而是为每个物理节点计算生成大量的、成百上千个虚拟节点,并把它们都分布到环上,这样,数据在环上找到的首先是一个虚拟节点,然后再映射到对应的物理节点,由于虚拟节点的数量远大于物理节点,并且是随机分布的,通过大量的虚拟节点,每个物理节点最终负责的环区间就会相对均匀很多,从而有效地解决了负载不均的问题,这就像是在一个不平整的桌子上垫了很多小垫片,最终让桌面变得平整了。
在Redis集群的实际应用中,正是这种结合了虚拟节点的一致性哈希算法,使得集群能够优雅地应对节点的加入和离开,既保证了系统的可扩展性,又避免了大规模数据迁移带来的性能抖动,成为了构建大规模分布式系统的关键技术之一。

本文由畅苗于2025-12-26发表在笙亿网络策划,如有疑问,请联系我们。
本文链接:http://waw.haoid.cn/wenda/68550.html
