首页 > 其他分享 >一致性哈希(哈希环)解决数据分布问题

一致性哈希(哈希环)解决数据分布问题

时间:2023-05-12 17:59:37浏览次数:102  
标签:缓存 机器 算法 数据分布 哈希 一致性 节点

哈希算法是程序开发过程中最广泛接触到的的算法之一,典型的应用有安全加密、数据校验、唯一标识、散列函数、负载均衡、数据分片、分布式存储。前些天遇到用一致性哈希(哈希环)的场景,不过我细想一下,对这个知识点好像了解过,但是又没太深印象,说不出具体是什么原理,怎么用,有哪些注意的地方。本文简单记录,希望也能给其他人作为初步了解所用。

1.诞生背景解决了怎么样的问题

一个常见的结论是在需要均匀的解决数据分布场景时通过引入一致性哈希算法可以很好解决此类问题。一致性哈希诞生,是麻省理工学院在1997年提出的一种分布式哈希(DHT)实现算法,其设计目标是为了解决因特网中的热点(Hot Spot)问题,将来自网络上的流量动态的均匀分发到不同的服务器处理。处理大量数据时很可能是遇到类似这样的难点:

  • 1.处理文件很大单台机器内存受限无法计算;
  • 2.如果单台机器处理这样大量数据处理耗时很大;

为了突破单机内存,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.总结和思考
一致性哈希主要解决数据分布场景,它存在这样的优点:

  • 1.可伸缩性
  • 2.负载平衡 (将节点与Hash算法解耦,而且通过交错分配虚拟节点的方式解决了负载不均衡导致的缓存热点问题)
    缺点(有个观点是用错了场景才是缺陷,用对了,那是特性):
  • 1.key值通过hash算法算出,映射固定,不灵活,而且节点数量变化时虚拟节点数量也会变化,这种耦合限制哈希算法进一步优化
  • 2.数据分布均匀,不代表流量和负载的均匀,热点key导致节点实际表现不均匀

5.参考资料
https://time.geekbang.org/column/article/67388
https://www.wikiwand.com/zh-cn/一致哈希
https://juejin.cn/post/7134656152452726792
https://www.geeksforgeeks.org/consistent-hashing-in-distributed-systems/
https://www.zsythink.net/archives/1182
https://blog.csdn.net/randompeople/article/details/103723839

标签:缓存,机器,算法,数据分布,哈希,一致性,节点
From: https://www.cnblogs.com/wangly/p/17395864.html

相关文章

  • hash哈希算法
    hash,-般翻译做散列、杂凑,或音译为哈希,是把任意长度的输入(又叫做预映射pre-image)通过散列算法变换成固定长度的输出,该输出就是散列值。这种转换是一种压缩映射,也就是,散列值的空间通常远小于输入的空间。它其实就是一个算法,最简单的算法就是加减乘除,比方,我设计个数字算法,输入+......
  • C/C++折半查找与哈希查找[2023-05-11]
    C/C++折半查找与哈希查找[2023-05-11]4、折半查找与哈希查找(难度等级A)[问题描述]查找是通过在查找表中做比较来完成的操作。折半查找与哈希查找都是利用数组实现的查找算法。通过本题,可以观察两种查找算法的性能。一般我们用平均查找长度ASL来表示一种查找算法的性能。ASL......
  • python基础学习-hashlib - 哈希函数模块
    hashlib-哈希函数模块参考地址:Python-Core-50-Courses/第20课:Python标准库初探.mdatmaster·jackfrued/Python-Core-50-Courses(github.com)待补充......哈希函数又称哈希算法或散列函数,是一种为已有的数据创建“数字指纹”(哈希摘要)的方法。哈希函数把数据压缩成摘要,对......
  • (第26章)LinuxC本质中链表、二叉树和哈希表
    文章目录一、单链表的结构决定只能出栈,入栈1.链表的结构2.链表与数组的区别3.单链表所有基本操作代码(1)链表的插入(2)链表的查找(3)链表的删除(3)遍历整个链表(4)销毁整个链表4.习题5.C++NULL指针二、双向链表结构决定可以出队和入队1.在上面的单项链表上改改,得到双向链表2.改进双向链表:新增......
  • 分布式一致性协议综述(下)
    本文首发自「慕课网」,想了解更多IT干货内容,程序员圈内热闻,欢迎关注"慕课网"!作者:大能老师|慕课网讲师 前情回顾:分布式一致性协议综述(上),需要回看请点击阅读Raft协议Paxos是论证了一致性协议的可行性,但是论证的过程据说晦涩难懂,缺少必要的实现细节,而且工程实现难度比较高广为人知实......
  • [Leetcode] 0705. 设计哈希集合
    705.设计哈希集合EnglishVersion题目描述不使用任何内建的哈希表库设计一个哈希集合(HashSet)。实现MyHashSet类:voidadd(key)向哈希集合中插入值key。boolcontains(key)返回哈希集合中是否存在这个值key。voidremove(key)将给定值key从哈希集合中删除。如果......
  • 5月4日:unordermap/set,哈希以及哈希常用的拉链法,开放地址法,以及模板的特化相关应用
    起处较为流行的数据储存方式为树形结构,再加上红黑树等优秀数据结构的发展,直到今天二叉平衡搜索树也经常被应用在各种方面,但是c++库里面还有两个与map/set很像的容器unorderedmap,他们的调用与普通的map几乎一样,有着非常优秀的查找时间复杂度,只是不能像二叉树哪样层序遍历得到顺序的......
  • 【算法】哈希算法
    1 前言本节我们来看我们常用的哈希算法哈。2  为什么要有哈希假设我们要设计一个系统来存储将员工手机号作为主键的员工记录,并希望高效地执行以下操作:插入电话号码和相应的信息。(插入)搜索电话号码并获取信息。(查找)删除电话号码及相关信息。(删除)我们可以考虑使用以下......
  • 哈希表
    要求O(1)查找元素的存在 structHashMap{staticconstintHash=999917,maxn=46340;intnum,link[Hash],son[maxn+5],next[maxn+5],w[maxn+5];inttop,Stack[maxn+5];voidclear(){num=0;while(top)link[Stack[top--]]=......
  • 哈希表与布隆过滤器
    一、哈希的整体思想最简单的哈希表其实就是数组,从数组中取出一个数的时间复杂度是O(1)的。但是数组下标类型是整型的,万一我的下标类型不是整型了该怎么办呢?比如说字符串型,典型的就是我想查找某个单词存不存在。还有些更复杂的数据类型,比如自定义的类型。那么问题就来了,如何满足任......