哈希算法是程序开发过程中最广泛接触到的的算法之一,典型的应用有安全加密、数据校验、唯一标识、散列函数、负载均衡、数据分片、分布式存储。前些天遇到用一致性哈希(哈希环)的场景,不过我细想一下,对这个知识点好像了解过,但是又没太深印象,说不出具体是什么原理,怎么用,有哪些注意的地方。本文简单记录,希望也能给其他人作为初步了解所用。
(资料图片仅供参考)
1.诞生背景解决了怎么样的问题
一个常见的结论是在需要均匀的解决数据分布场景时通过引入一致性哈希算法可以很好解决此类问题。一致性哈希诞生,是麻省理工学院在1997年提出的一种分布式哈希(DHT)实现算法,其设计目标是为了解决因特网中的热点(Hot Spot)问题,将来自网络上的流量动态的均匀分发到不同的服务器处理。处理大量数据时很可能是遇到类似这样的难点:
为了突破单机内存,cup资源限制,借助分片思路,先切分数据,再利用多台机器提高处理速度,最后在合并起来得到最终结果,这个处理过程也是MapReduce的基本思想,不过再思考一下,仅仅是解决上面问题话,一个普通的哈希算法就能解决;为什么会要引入一致性哈希算法呢?
当数据增多,需要扩容机器时,直接加上新机器,那么所有数据会遇到一个问题,就是之前哈希值不对了,通常哈希值计算和机器数量有关,最简单就是对机器数量取模,当数量变化是需要重新计算哈希值,然后搬移数据到正确的机器上,用在缓存场景就相当于所有缓存失效,请求数据穿透缓存,直接请求数据库,这样就很容易发生雪崩效应。所以就需要一种新方法,让加入机器后,不需要做大量数据迁移。
2.原理介绍
一致性哈希原理介绍 一致性哈希是一种用于分布式系统中数据分片和负载均衡的算法。它的核心思想是将数据根据哈希值映射到一个环形空间中,然后将节点也映射到环上。当需要查找某个数据时,先计算该数据的哈希值,然后沿着环的顺时针方向找到第一个大于等于该哈希值的节点,即为该数据所在的节点。这样可以将数据均匀地分布在各个节点上,并且在节点动态添加或删除时,只需要重新映射该节点的哈希值,而不需要重新映射所有数据的哈希值,从而避免了数据迁移的开销。一致性哈希算法的优点是具有高度的可扩展性和容错性,能够自动适应节点的动态变化,同时保证数据的一致性和负载均衡。它被广泛应用于分布式缓存、分布式数据库、负载均衡等领域。Powered by ChatGPT
再借用大牛们对一致性哈希原理介绍的,通过hash函数映射到一个哈希环上,哈希环可以理解为一个连续变好的循环链表,一般会用32位的哈希值,可以映射2^32个值。
假设key1和key2经过计算都命中哈希环上一个机器节点0,此时新加入一个节点n,节点n接管了部分原来归属于节点0的区域(只有key2在其中),此时再次访问key1和key2,只会有key2因为变更节点,需要重新迁移数据。
3.一致性哈希优点从上面原理介绍,我们可以很容易看到一致性哈希算法在可伸缩性的优点,我们简单模拟下看看是否解决之前的雪崩问题,另外这里我们再讨论下它均衡性优点。我们模拟一下当机器B故障,需要在服务列表里摘除机器B。我们直接将故障机器B从哈希环上移除,原来归属于机器B的数据按照一致性哈希规则,应该被缓存到哈希环上下一个机器节点例如机器C。其他数据并不会因此产生变化,只有一部分缓存失败需要重新构建,从而不至于所有全部缓存失效导致的雪崩效应问题。不过就像买家秀和买家秀的巨大差距一样,通常理想很丰满,现实很骨感。只是按照上述定义,哈希环上机器映射大概率是没法均分的,缓存对象很大可能被集中在某一台机器上,分布极度不均,产生hash环的偏斜,极端情况下,仍然可能引起系统崩溃。所以一致性哈希算法中使用‘虚拟节点’解决这个问题。所谓‘虚拟节点’就是有实际节点虚拟复制而来的节点,填充在哈希环上,让机器尽量多,均匀的出现在哈希环上,所以通常是一个实际节点对应多个虚拟节点。有虚拟节点加入后再看哈希环,我们就可以达到良好的均衡性,减少哈希环偏斜带来的影响,缓存也就被均匀分布概率越大。
4.总结和思考一致性哈希主要解决数据分布场景,它存在这样的优点:
5.参考资料https://time.geekbang.org/column/article/67388https://www.wikiwand.com/zh-cn/一致哈希https://juejin.cn/post/7134656152452726792https://www.geeksforgeeks.org/consistent-hashing-in-distributed-systems/https://www.zsythink.net/archives/1182https://blog.csdn.net/randompeople/article/details/103723839
标签: