专栏电商日志财经减肥爱情
投稿投诉
爱情常识
搭配分娩
减肥两性
孕期塑形
财经教案
论文美文
日志体育
养生学堂
电商科学
头戴业界
专栏星座
用品音乐

图解一致性哈希算法,看这一篇就够了

  近段时间一直在总结分布式系统架构常见的算法。前面我们介绍过布隆过滤器算法。接下来介绍一个非常重要、也非常实用的算法:一致性哈希算法。通过介绍一致性哈希算法的原理并给出了一种实现和实际运用的案例,带大家真正理解一致性哈希算法。一、背景
  在具体介绍一致性哈希算法之前,先问一个问题:为什么需要一致性哈希算法?下面我们通过一个案例来回答这个问题。
  假设有这么一种场景:我们有三台缓存服务器分别为:node0、node1、node2,有3000万个缓存数据需要存储在这三台服务器组成的集群中,希望可以将这些数据均匀的缓存到三台机器上,你会想到什么方案呢?
  我们可能首先想到的方案是:取模算法hash(key)N,即:对缓存数据的key进行hash运算后取模,N是机器的数量;运算后的结果映射对应集群中的节点。具体如下图所示:
  如上图所示,首先对key进行hash计算后的结果对3取模,得到的结果一定是0、1或者2;然后映射对应的服务器node0、node1、node2,最后直接找对应的服务器存取数据即可。
  通过取模算法将每个数据请求都均匀地分散到了三个不同的服务器节点上,看起来很完美!但是,在分布式集群系统的负载均衡实现上,这种模型在集群扩容和收缩时却有一定的局限性:因为在生产环境中根据业务量的大小,调整服务器数量是常有的事,而服务器数量N发生变化后hash(key)N计算的结果也会随之变化!导致整个集群的缓存数据必须重新计算调整,进而导致大量缓存在同一时间失效,造成缓存的雪崩,最终导致整个缓存系统的不可用,这是不能接受的。为了解决优化上述情况,一致性哈希算法应运而生。二、一致性哈希简介
  有些朋友一听到算法就头大,其实大可不必,一致性哈希算法听起来高大上,其实非常简单。接下来开始介绍什么是一致性哈希算法,它解决了什么问题。2。1什么是一致性哈希?
  一致性哈希(ConsistentHash)算法是1997年提出,是一种特殊的哈希算法,目的是解决分布式系统的数据分区问题:当分布式集群移除或者添加一个服务器时,必须尽可能小地改变已存在的服务请求与处理请求服务器之间的映射关系。2。2一致性哈希主要解决问题
  我们知道,传统的按服务器节点数量取模在集群扩容和收缩时存在一定的局限性。而一致性哈希算法正好解决了简单哈希算法在分布式集群中存在的动态伸缩的问题。降低节点上下线的过程中带来的数据迁移成本,同时节点数量的变化与分片原则对于应用系统来说是无感的,使上层应用更专注于领域内逻辑的编写,使得整个系统架构能够动态伸缩,更加灵活方便。2。3一致性哈希的使用场景
  一致性哈希算法是分布式系统中的重要算法,使用场景也非常广泛。主要是是负载均衡、缓存数据分区等场景。
  一致性哈希应该是实现负载均衡的首选算法,它的实现比较灵活,既可以在客户端实现,也可以在中间件上实现,比如日常使用较多的缓存中间件memcached使用的路由算法用的就是一致性哈希算法。
  此外,其它的应用场景还有很多:RPC框架Dubbo用来选择服务提供者分布式关系数据库分库分表:数据与节点的映射关系LVS负载均衡调度器
  三、一致性哈希的原理2。1算法原理
  前面介绍的取模算法虽然使用简单,但缺陷也很明显,如果服务器中保存有服务请求对应的数据,那么如果重新计算请求的哈希值,会造成缓存的雪崩的问题。这种情况在分布式系统中是非常糟糕的。一个设计良好的分布式系统应该具有良好的单调性,即服务器的添加与移除不会造成大量的哈希重定位,而一致性哈希恰好可以解决这个问题。
  其实,一致性哈希算法本质上也是一种取模算法。只不过前面介绍的取模算法是按服务器数量取模,而一致性哈希算法是对固定值232取模,这就使得一致性算法具备良好的单调性:不管集群中有多少个节点,只要key值固定,那所请求的服务器节点也同样是固定的。其算法的工作原理如下:一致性哈希算法将整个哈希值空间映射成一个虚拟的圆环,整个哈希空间的取值范围为02321;计算各服务器节点的哈希值,并映射到哈希环上;将服务发来的数据请求使用哈希算法算出对应的哈希值;将计算的哈希值映射到哈希环上,同时沿圆环顺时针方向查找,遇到的第一台服务器就是所对应的处理请求服务器。当增加或者删除一台服务器时,受影响的数据仅仅是新添加或删除的服务器到其环空间中前一台的服务器(也就是顺着逆时针方向遇到的第一台服务器)之间的数据,其他都不会受到影响。
  综上所述,一致性哈希算法对于节点的增减都只需重定位环空间中的一小部分数据,具有较好的容错性和可扩展性。
  2。2深入剖析
  说了那么多,可能你还是云里雾里的,那么接下来我们详细剖析一致性哈希的实现原理。2。2。1哈希环
  首先,一致性哈希算法将整个哈希值空间映射成一个虚拟的圆环。整个哈希空间的取值范围为02321,按顺时针方向开始从02321排列,最后的节点2321在0开始位置重合,形成一个虚拟的圆环。如下图所示:
  2。2。2服务器映射到哈希环
  接下来,将服务器节点映射到哈希环上对应的位置。我们可以对服务器IP地址进行哈希计算,哈希计算后的结果对232取模,结果一定是一个0到2321之间的整数。最后将这个整数映射在哈希环上,整数的值就代表了一个服务器节点的在哈希环上的位置。即:hash(服务器ip)232。下面我们依次将node0、node1、node2三个缓存服务器映射到哈希环上,如下图所示:
  2。2。3对象key映射到服务器
  当服务器接收到数据请求时,首先需要计算请求Key的哈希值;然后将计算的哈希值映射到哈希环上的具体位置;接下来,从这个位置沿着哈希环顺时针查找,遇到的第一个节点就是key对应的节点;最后,将请求发送到具体的服务器节点执行数据操作。
  假设我们有key01:张三、key02:李四、key03:王五三条缓存数据。经过哈希算法计算后,映射到哈希环上的位置如下图所示:
  如上图所示,通过哈希计算后,key01顺时针寻找将找到node0,key02顺时针寻找将找到node1,key03顺时针寻找将找到node2。最后,请求找到的服务器节点执行具体的业务操作。
  以上便是一致性哈希算法的工作原理。四、服务器扩容缩容
  前面介绍了一致性哈希算法的工作原理,那么,一致性哈希算法如何避免服务器动态伸缩的问题的呢?4。1服务器缩容
  服务器缩容就是减少集群中服务器节点的数量或是集群中某个节点的故障。假设,集群中的某个节点故障,原本映射到该节点的请求,会找到哈希环中的下一个节点,数据也同样被重新分配至下一个节点,其它节点的数据和请求不受任何影响。这样就确保节点发生故障时,集群能保持正常稳定。如下图所示:
  如上图所示:节点node2发生故障时,数据key01和key02不会受到影响,只有key03的请求被重定位到node0。在一致性哈希算法中,如果某个节点宕机不可用了,那么受影响的数据仅仅是会寻址到此节点和前一节点之间的数据。其他哈希环上的数据不会受到影响。4。2服务器扩容
  服务器扩容就是集群中需要增加一个新的数据节点,假设,由于需要缓存的数据量太大,必须对集群进行扩容增加一个新的数据节点。此时,只需要计算新节点的哈希值并将新的节点加入到哈希环中,然后将哈希环中从上一个节点到新节点的数据映射到新的数据节点即可。其他节点数据不受影响,具体如下图所示:
  如上图所示,加入新的node3节点后,key01、key02不受影响,只有key03的寻址被重定位到新节点node3,受影响的数据仅仅是会寻址到新节点和前一节点之间的数据。
  通过一致性哈希算法,集群扩容或缩容时,只需要重新定位哈希环空间内的一小部分数据。其他数据保持不变。当节点数越多的时候,使用哈希算法时,需要迁移的数据就越多,使用一致哈希时,需要迁移的数据就越少。所以,一致哈希算法具有较好的容错性和可扩展性。五、数据倾斜与虚拟节点5。1什么是数据倾斜?
  前面说了一致性哈希算法的原理以及扩容缩容的问题。但是,由于哈希计算的随机性,导致一致性哈希算法存在一个致命问题:数据倾斜,,也就是说大多数访问请求都会集中少量几个节点的情况。特别是节点太少的情况下,容易因为节点分布不均匀造成数据访问的冷热不均。这就失去了集群和负载均衡的意义。如下图所示:
  如上图所示,key1、key2、key3可能被映射到同一个节点node0上。导致node0负载过大,而node1和node2却很空闲的情况。这有可能导致个别服务器数据和请求压力过大和崩溃,进而引起集群的崩溃。5。2如何解决数据倾斜?
  为了解决数据倾斜的问题,一致性哈希算法引入了虚拟节点机制,即对每一个物理服务节点映射多个虚拟节点,将这些虚拟节点计算哈希值并映射到哈希环上,当请求找到某个虚拟节点后,将被重新映射到具体的物理节点。虚拟节点越多,哈希环上的节点就越多,数据分布就越均匀,从而避免了数据倾斜的问题。
  说起来可能比较复杂,一句话概括起来就是:原有的节点、数据定位的哈希算法不变,只是多了一步虚拟节点到实际节点的映射。具体如下图所示:
  如上图所示,我们可以在服务器ip或主机名的后面增加编号来实现,将全部的虚拟节点加入到哈希环中,增加了节点后,数据在哈希环上的分布就相对均匀了。当有访问请求寻址到node01这个虚拟节点时,将被重新映射到物理节点node0。六、一致性Hash算法实现
  前面介绍了一致性哈希算法的原理、动态伸缩以及数据倾斜的问题后,下面我们根据上面的讲述,使用Java实现一个简单的一致性哈希算法。6。1数据节点
  首先定义一个节点类,实现数据节点的功能,具体代码如下:publicclassNode{privatestaticfinalintVIRTUALNODENOPERNODE200;privatefinalStringip;privatefinalListIntegervirtualNodeHashesnewArrayList(VIRTUALNODENOPERNODE);privatefinalMapObject,ObjectcacheMapnewHashMap();publicNode(Stringip){Objects。requireNonNull(ip);this。ipip;initVirtualNodes();}privatevoidinitVirtualNodes(){StringvirtualNodeKey;for(inti1;iVIRTUALNODENOPERNODE;i){virtualNodeKeyipi;virtualNodeHashes。add(HashUtils。hashcode(virtualNodeKey));}}publicvoidaddCacheItem(Objectkey,Objectvalue){cacheMap。put(key,value);}publicObjectgetCacheItem(Objectkey){returncacheMap。get(key);}publicvoidremoveCacheItem(Objectkey){cacheMap。remove(key);}publicListIntegergetVirtualNodeHashes(){returnvirtualNodeHashes;}publicStringgetIp(){returnip;}}
  6。2实现一致性哈希算法
  接下来实现核心功能:一致性哈希算法,主要使用java的TreeMap类,实现哈希环和哈希查找的功能。具体代码如下所示:publicclassConsistentHash{privatefinalTreeMapInteger,NodehashRingnewTreeMap();publicListNodenodeListnewArrayList();增加节点每增加一个节点,就会在闭环上增加给定虚拟节点例如虚拟节点数是2,则每调用此方法一次,增加两个虚拟节点,这两个节点指向同一NodeparamippublicvoidaddNode(Stringip){Objects。requireNonNull(ip);NodenodenewNode(ip);nodeList。add(node);for(IntegervirtualNodeHash:node。getVirtualNodeHashes()){hashRing。put(virtualNodeHash,node);System。out。println(虚拟节点〔node〕hash:virtualNodeHash,被添加);}}移除节点paramnodepublicvoidremoveNode(Nodenode){nodeList。remove(node);}获取缓存数据先找到对应的虚拟节点,然后映射到物理节点paramkeyreturnpublicObjectget(Objectkey){NodenodefindMatchNode(key);System。out。println(获取到节点:node。getIp());returnnode。getCacheItem(key);}添加缓存先找到hash环上的节点,然后在对应的节点上添加数据缓存paramkeyparamvaluepublicvoidput(Objectkey,Objectvalue){NodenodefindMatchNode(key);node。addCacheItem(key,value);}删除缓存数据publicvoidevict(Objectkey){findMatchNode(key)。removeCacheItem(key);}获得一个最近的顺时针节点paramkey为给定键取Hash,取得顺时针方向上最近的一个虚拟节点对应的实际节点return节点对象returnprivateNodefindMatchNode(Objectkey){Map。EntryInteger,NodeentryhashRing。ceilingEntry(HashUtils。hashcode(key));if(entrynull){entryhashRing。firstEntry();}returnentry。getValue();}}
  如上所示,通过TreeMap的ceilingEntry()方法,实现顺时针查找下一个的服务器节点的功能。
  6。3哈希计算方法
  哈希计算方法比较常见,网上也有很多计算hash值的函数。示例代码如下:publicclassHashUtils{FNV132HASHparamobjobjectreturnhashcodepublicstaticinthashcode(Objectobj){finalintp16777619;inthash(int)2166136261L;Stringstrobj。toString();for(inti0;istr。length();i)hash(hashstr。charAt(i))p;hashhash13;hashhash7;hashhash3;hashhash17;hashhash5;if(hash0)hashMath。abs(hash);System。out。println(hashcomputer:hash);returnhash;}}
  6。4验证测试
  一致性哈希算法实现后,接下来添加一个测试类,验证此算法时候正常。示例代码如下:publicclassConsistentHashTest{publicstaticfinalintNODESIZE10;publicstaticfinalintSTRINGCOUNT100100;privatestaticConsistentHashconsistentHashnewConsistentHash();privatestaticListStringsListnewArrayList();publicstaticvoidmain(String〔〕args){增加节点for(inti0;iNODESIZE;i){StringipnewStringBuilder(10。2。1。)。append(i)。toString();consistentHash。addNode(ip);}生成需要缓存的数据;for(inti0;iSTRINGCOUNT;i){sList。add(RandomStringUtils。randomAlphanumeric(10));}将数据放入到缓存中。for(Strings:sList){consistentHash。put(s,s);}for(inti0;i10;i){intindexRandomUtils。nextInt(0,STRINGCOUNT);StringkeysList。get(index);Stringcache(String)consistentHash。get(key);System。out。println(Random:index,key:key,consistentHashgetvalue:cache,valueis:key。equals(cache));}输出节点及数据分布情况for(Nodenode:consistentHash。nodeList){System。out。println(node);}新增一个数据节点consistentHash。addNode(10。2。1。110);for(inti0;i10;i){intindexRandomUtils。nextInt(0,STRINGCOUNT);StringkeysList。get(index);Stringcache(String)consistentHash。get(key);System。out。println(Random:index,key:key,consistentHashgetvalue:cache,valueis:key。equals(cache));}输出节点及数据分布情况for(Nodenode:consistentHash。nodeList){System。out。println(node);}}}
  运行此测试,输出结果如下所示:
  最后
  以上,我们就把一致性哈希算法的实现原理,应用场景、解决了哪些问题都介绍完了,并用java简单实现了一个一致性哈希算法。相信看完之后,大家对一致性哈希算法应该不会那么陌生害怕了吧。

兔年首个工作日,沪上企业纷纷派发开工利是激励员工今天是大年初七,兔年新春开工第一天,许多职场人都收到了惊喜开工利是。不少企业都有这种仪式感,派送红包让大家欢欢喜喜,热热闹闹,同时也象征着开工大吉,生意兴隆。有些企业不仅给员工发开开工利是现身兔年首个工作日本报讯(劳动报记者陈宁文摄)昨天是大年初七,兔年新春开工第一天,许多职场人都收到了惊喜开工利是。不少企业都有这种仪式感,派送红包让大家欢欢喜喜,热热闹闹,同时也象征着开工大吉,生意张本智和跌到第4,樊振东稳居第1!兔年乒乓排名出炉,中国队领先头条创作挑战赛张本智和跌到第4,樊振东稳居第1!兔年乒乓排名出炉,中国绝对领先北京时间2023年1月26日星期四消息。进入到2023年,也就意味着俱乐部2024年巴黎奥运会,只剩最回乡的路见到村口大樟树如见亲人,父母在是家乡,父母去是故乡回乡的路,父母在是家乡,父母去是故乡。这些年从来没有乡愁,是因为从小到大家乡有父母的影子。终于有一天,父亲走了,母亲也苟延残喘,我突然感觉自己的内心被掏空了,以后回乡的路没有方向感论汉朝与匈奴的和亲政策历史上最早的和亲可以追溯到商朝,为加强和各个部落之间的联系,商王赏赐给部落首领官职财物,还顺便帮他们解决婚姻问题,通过联姻的方式,加强二者之间的联系,使彼此关系更加稳固,有利于统治国际机构中国财政空间充足将支持经济稳健复苏视频加载中(央视财经经济信息联播)多家国际机构与投行的专家认为,中国宏观政策发力将支持经济稳健复苏。金砖国家新开发银行副行长马斯多普中国有充足的财政空间,帮助中国经济在重启后的调整感觉都回来了?泰伦卢仍然有很长路要走但我真感觉情况不同了直播吧1月27日讯NBA常规赛,快船主场138100大胜马刺。赛后,快船主教练泰伦卢谈到了快船队近期的表现,他说我感觉他们(快船队)变得不太一样了!虽然就像我一直说的那样,我们仍然春节期间,世界发生了一件大事!情况严峻,我们该怎么办?头条创作挑战赛中国在热热闹闹过春节的时候,世界也很热闹。作为一名老兵,有一件极为危险的大事儿不得不关注。那就是俄乌冲突的走向,极有可能触发二战以来人类和平最为危险的那根弦儿,甚至有世卫更新应对辐射和核紧急情况关键药物清单各国政府必须做好准备环球网报道世界卫生组织敦促各国储备以应对核紧急情况俄罗斯卫星通讯社28日以此为题的报道注意到,世卫组织27日在其官网更新了应对辐射和核紧急情况建议储备的药物清单,这是自2007年以建队核心!曝朱婷将续约斯坎迪奇,高层100信任,冲击双冠王进入到农历2023年新年之后,斯坎迪奇的成绩不佳,先后不敌诺瓦拉和贝加莫,其中联赛不敌诺瓦拉之后让后者顺利杀入前四,意大利杯输给贝加莫之后无缘四强,国内杯赛正式出局。姚迪作为斯坎迪看到俄罗斯的处境,更加钦佩周总理的两句话,正中目前的情况文史纪奇闻编辑史纪奇闻谁还曾记得普京2000年出任总统时的豪言壮语,给我20年,还你一个强大的俄罗斯!如今20年过去了,现在的俄罗斯是否如他所言真的强大起来了呢?01冲突爆发202
高淳慢城3条绝美骑行路线,秋日共赏诗和远方秋风一过,山野被洒上金黄的碎片画家绘制着凉爽秋日的唯美画卷好不容易熬过了一周的工作日不妨放下手机,出门来场骑行放松屋内久坐的身体感受高淳秋日恰好的风度01慢城线网络如果你是一个骑行家门口的这些公园洋溢着秋日烂漫成渝之心内江好耍去过闹中取静的大千园,去过赫赫有名的塔山公园,内江还有哪些公园值得打卡?国庆假期最后一天,封面新闻带大家走进几个公园,来看都有哪些别样景致。小青龙河创客公园小青龙河创客公园(图片来春有桃花夏有荷,秋有落叶冬有雪,武汉的秋天美得让人难忘春有桃花夏有荷,秋有落叶冬有雪。北方城市纷飞的白雪喜提了多次热搜,而南方城市还徜徉在满目金黄的秋意之中。至从2020年武汉出现新型的冠状病毒至今,我已经有快3年的时间没有来过这个城八达岭十三陵一日游旅行笔记,难忘的一天八达岭长城介绍八达岭长城史称天下九塞之一,是万里长城的精华,独具代表性。八达岭长城是万里长城向游人开得最早的地段,所以周围的餐饮及设施还是相当完善的八达岭长城交通方式公交从积水潭地迪丽热巴穿粉色格子衣,甜美灵动的酷飒风格,散发出女人的魅力迪丽热巴身穿粉色格子衣,甜美灵动的酷飒风格,瞬间吸引不少人的目光。当迪丽热巴晒出这组美照时,这组美照就是迪丽热巴女团的造型,青春靓丽的形象,充满着元气满满的少女感。迪丽热巴以这样的这才是560岁女人该有的打扮风衣膝下裙,优雅遮肉还有气质得体优雅的穿衣打扮永远都是560随阶段的首要呈现穿搭,这个阶段真的不必要一味的追求时髦感和个性感,彰显温柔大气的气质效果才能够体现中年女性的专属魅力,那么单品的选择结合就很重要啦!走他人不走的路主题说走他人不走的路下面我们一起去看看名人名言赖声川为我们分享今日咱们的标题,是走跟他人不同的路,但这究竟是什么意思,你不要误解,这个意思不是说你要去寻觅一个绝无仅有的,他人没有走比起三亚它略逊一筹,但这里物价低廉,交通医疗便利,环境还好提到冬日旅行的好去处,大家的脑海当中第一时间想到的一定是去冬暖夏凉的海滨城市过冬天,像什么海南,三亚,青岛等一系列的海滨城市,确实,这些城市的冬天大多气候温暖,风景优美,环境宜人,王晶32岁女儿真豪放,穿露脐装牛仔裤秀身材,颜值太低没有辨识度对于女性而言,CropTop是一种时尚又潮流的单品,多见于年轻女孩。不管是露脐装还是露胃装,懂得驾驭,就能让自己看起来性感迷人,提升自己的魅力。另外,这样的单品还能帮助改变身材比例被CNN评为中国最美地!一入秋便美成了山水画当下最受欢迎的旅游目的地,除了万年不变的海岛三亚冬季滑雪热长白山,入秋的徽州绝对排得上前三!诗中有言,一生痴绝处,无梦到徽州。国内入秋华南地区最好的风景都在徽州地区了随着全国各地开数字赋能,一码游模式引领新一轮智慧文旅发展趋势近年来,为适应地方文旅行业发展的需求,各景区抢抓数字经济发展机遇,创新探索智慧景区建设,一码游模式以数字赋能资源聚合社会协同等突出优势应运而生,引领了新一轮智慧文旅发展趋势。区别于
友情链接:快好知快生活快百科快传网中准网文好找聚热点快软网