不会一致性hash算法,劝你简历别写搞过负载均衡

Jetson AGX Orin 新手避坑:解决‘找不到nvidia-jetpack包’的完整修复指南 本文详细介绍了Jetson AGX Orin设备在安装JetPack开发套件时遇到的'nvidia-jetpack包缺失'问题的完整解决方案。通过分析问题根源、提供分步修复指南以及系统优化建议,帮助开发者快速解决这一常见问题,充分发挥Jetson AGX Orin的边缘计算性能。 阅读详情

这两天看到技术群里,有小伙伴在讨论一致性hash算法的问题,正愁没啥写的题目就来了,那就简单介绍下它的原理。下边我们以分布式缓存中经典场景举例,面试中也是经常提及的一些话题,看看什么是一致性hash算法以及它有那些过人之处。

c80bd30847100a71b21a5314c5034b9b.png

构建场景

假如我们有三台缓存服务器编号node0、node1、node2,现在有3000万个key,希望可以将这些个key均匀的缓存到三台机器上,你会想到什么方案呢?

我们可能首先想到的方案,是取模算法hash(key)% N,对key进行hash运算后取模,N是机器的数量。key进行hash后的结果对3取模,得到的结果一定是0、1或者2,正好对应服务器node0、node1、node2,存取数据直接找对应的服务器即可,简单粗暴,完全可以解决上述的问题。

0eb4fd33dd157351a35a2809fcf5044a.png

hash的问题

取模算法虽然使用简单,但对机器数量取模,在集群扩容和收缩时却有一定的局限性,因为在生产环境中根据业务量的大小,调整服务器数量是常有的事;而服务器数量N发生变化后hash(key)% N计算的结果也会随之变化。

af7bc0454e7551a37fa7798e0763e007.png

比如:一个服务器节点挂了,计算公式从hash(key)% 3变成了hash(key)% 2,结果会发生变化,此时想要访问一个key,这个key的缓存位置大概率会发生改变,那么之前缓存key的数据也会失去作用与意义。

大量缓存在同一时间失效,造成缓存的雪崩,进而导致整个缓存系统的不可用,这基本上是不能接受的,为了解决优化上述情况,一致性hash算法应运而生~

那么,一致性哈希算法又是如何解决上述问题的?

一致性hash

一致性hash算法本质上也是一种取模算法,不过,不同于上边按服务器数量取模,一致性hash是对固定值2^32取模。

“

IPv4的地址是4组8位2进制数组成,所以用2^32可以保证每个IP地址会有唯一的映射

hash环

我们可以将这2^32个值抽象成一个圆环⭕️(不得意圆的,自己想个形状,好理解就行),圆环的正上方的点代表0,顺时针排列,以此类推,1、2、3、4、5、6……直到2^32-1,而这个由2的32次方个点组成的圆环统称为hash环。

3b0ecbd32ad3c6b188e92ca0bce2153a.png

那么这个hash环和一致性hash算法又有什么关系嘞?我们还是以上边的场景为例,三台缓存服务器编号node0、node1、node2,3000万个key。

服务器映射到hash环

这个时候计算公式就从hash(key)% N 变成了hash(服务器ip)% 2^32,使用服务器IP地址进行hash计算,用哈希后的结果对2^32取模,结果一定是一个0到2^32-1之间的整数,而这个整数映射在hash环上的位置代表了一个服务器,依次将node0、node1、node2三个缓存服务器映射到hash环上。

c55754a75a7d971a26f8a8b287306739.png

对象key映射到hash环

接着在将需要缓存的key对象也映射到hash环上,hash(key)% 2^32,服务器节点和要缓存的key对象都映射到了hash环,那对象key具体应该缓存到哪个服务器上呢?

ce6ef28f170f2269941b8c72254f5b50.png

对象key映射到服务器

“

从缓存对象key的位置开始,沿顺时针方向遇到的第一个服务器,便是当前对象将要缓存到的服务器。

因为被缓存对象与服务器hash后的值是固定的,所以,在服务器不变的条件下,对象key必定会被缓存到固定的服务器上。根据上边的规则,下图中的映射关系:

  • key-1 -> node-1

  • key-3 -> node-2

  • key-4 -> node-2

  • key-5 -> node-2

  • key-2 -> node-0

b3d985e45c8d4176f2b5ac766604dd95.png

如果想要访问某个key,只要使用相同的计算方式,即可得知这个key被缓存在哪个服务器上了。

一致性hash的优势

我们简单了解了一致性hash的原理,那它又是如何优化集群中添加节点和缩减节点,普通取模算法导致的缓存服务,大面积不可用的问题呢?

先来看看扩容的场景,假如业务量激增,系统需要进行扩容增加一台服务器node-4,刚好node-4被映射到node-1和node-2之间,沿顺时针方向对象映射节点,发现原本缓存在node-2上的对象key-4、key-5被重新映射到了node-4上,而整个扩容过程中受影响的只有node-4和node-1节点之间的一小部分数据。

f6035ccccea653639ac7d9f13312ddfb.png

反之,假如node-1节点宕机,沿顺时针方向对象映射节点,缓存在node-1上的对象key-1被重新映射到了node-4上,此时受影响的数据只有node-0和node-1之间的一小部分数据。

907ca1e08c71e8b59d3f56e22407968f.png

从上边的两种情况发现,当集群中服务器的数量发生改变时,一致性hash算只会影响少部分的数据,保证了缓存系统整体还可以对外提供服务的。

数据偏斜问题

前边为了便于理解原理,画图中的node节点都很理想化的相对均匀分布,但理想和实际的场景往往差别很大,就比如办了个健身年卡的我,只去过健身房两次,还只是洗了个澡。

81ed42ea9308429ef693f1388cf94431.png
想要健身的你

在服务器节点数量太少的情况下,很容易因为节点分布不均匀而造成数据倾斜问题,如下图被缓存的对象大部分缓存在node-4服务器上,导致其他节点资源浪费,系统压力大部分集中在node-4节点上,这样的集群是非常不健康的。

c9d243252f2400f34ea30e5a6379befc.png

解决数据倾斜的办法也简单,我们就要想办法让节点映射到hash环上时,相对分布均匀一点。

一致性Hash算法引入了一个虚拟节点机制,即对每个服务器节点计算出多个hash值,它们都会映射到hash环上,映射到这些虚拟节点的对象key,最终会缓存在真实的节点上。

虚拟节点的hash计算通常可以采用,对应节点的IP地址加数字编号后缀 hash(10.24.23.227#1) 的方式,举个例子,node-1节点IP为10.24.23.227,正常计算node-1的hash值。

  • hash(10.24.23.227#1)% 2^32

假设我们给node-1设置三个虚拟节点,node-1#1、node-1#2、node-1#3,对它们进行hash后取模。

  • hash(10.24.23.227#1)% 2^32

  • hash(10.24.23.227#2)% 2^32

  • hash(10.24.23.227#3)% 2^32

下图加入虚拟节点后,原有节点在hash环上分布的就相对均匀了,其余节点压力得到了分摊。

3e49a071a00c0fd1d7ec1e9a9b97ee76.png
“

但需要注意一点,分配的虚拟节点个数越多,映射在hash环上才会越趋于均匀,节点太少的话很难看出效果

引入虚拟节点的同时也增加了新的问题,要做虚拟节点和真实节点间的映射,对象key->虚拟节点->实际节点之间的转换。

cfbb88224e3b4d614aadca526e1dd755.png

一致性hash的应用场景

一致性hash在分布式系统中应该是实现负载均衡的首选算法,它的实现比较灵活,既可以在客户端实现,也可以在中间件上实现,比如日常使用较多的缓存中间件memcached和redis集群都有用到它。

memcached的集群比较特殊,严格来说它只能算是伪集群,因为它的服务器之间不能通信,请求的分发路由完全靠客户端来的计算出缓存对象应该落在哪个服务器上,而它的路由算法用的就是一致性hash。

51be7ec203dff6f95ccac94466c753cd.png

还有redis集群中hash槽的概念,虽然实现不尽相同,但思想万变不离其宗,看完本篇的一致性hash,你再去理解redis槽位就轻松多了。

其它的应用场景还有很多:

  • RPC框架Dubbo用来选择服务提供者

  • 分布式关系数据库分库分表:数据与节点的映射关系

  • LVS负载均衡调度器

  • .....................

总结

简单的阐述了下一致性hash,如果有不对的地方大家可以留言指正,任何技术都不会十全十美,一致性Hash算法也是有一些潜在隐患的,如果Hash环上的节点数量非常庞大或者更新频繁时,检索性能会比较低下,而且整个分布式缓存需要一个路由服务来做负载均衡,一旦路由服务挂了,整个缓存也就不可用了,还要考虑做高可用。

不过话说回来,只要是能解决问题的都是好技术,有点副作用还是可以忍受的。

基于Simulink的PID控制器自动驾驶仿真建模示例 本文通过Simulink仿真平台,详细讲解了基于PID控制器的自动驾驶路径跟踪实现方法。主要内容包括:1)建立自行车运动学模型作为被控对象;2)定义参考路径与横向误差计算方法;3)设计PD控制器并调试参数;4)在Simulink中搭建完整仿真模型;5)分析30km/h车速下的双移线跟踪性能。文章强调PID控制作为自动驾驶入门基础的重要性,并指出其在中低速场景下的适用性,同时给出了工程实践中的优化建议(如前视距离、抗积分饱和等)和扩展方向(如Stanley控制器)。通过完整案例,帮助读者掌握车辆运动学建模和P 阅读详情

相关推荐

XY2-100协议解析

1.XY2-100包括四路信号 : SENDCK(时钟信号)、SYNC(同步信号)、CHANNELX(X通道)、CHANNELY(Y通道)

qq_38360574的博客 9536

深入浅出一致性Hash原理,及问题解决

深入浅出一致性Hash原理,及问题解决

weixin_39094034的博客 650

手写数字数据集MNIST

文章目录一、 简介二、下载MNIST数据集训练集和测试集的长度输出图像数据和标记数据的形状显示手写数字图片输出数据集中的第1个样本显示图片 一、 简介 MNIST是一个非常有名的手写体数字识别数据集(手写数字灰度图像数据集),在很多资料中,这个数据集都会被用作深度学习的入门样例。 MNIST数据集是由0到9的数字图像构成的。训练图像有6万张,测试图像有1万张。MNIST数据集是NIST数据集的一个子集,它包含了60000张图片作为训练数据,10000张图片作为测试数据。由250个不同的人手写而成。 每一张图

qq_37289115的博客 1万+

关于一致性哈希的一点理解

一致性哈希是分布式哈希表(DHT)其中一种实现,如读者还不是很了解分布式哈希可以阅读这篇博客 在开始介绍一致性哈希概念之前,让我们先来看看 ...

Ryanqy的专栏 607

MTK-Display技术解析:从MDP到DDP的架构演进

本文深入解析了联发科(MTK)显示技术从MDP到DDP的架构演进。MDP作为多媒体数据预处理中心,负责格式转换与缩放;而DDP则整合了OVL、COLOR、AAL等模块,并引入CMDQ与场景化模式,实现了从分散处理到统一智能调度的飞跃,旨在提升画质、流畅度并降低功耗。

weixin_29218509的博客 257

金证股份软件测试笔试题面试题

boss上这家公司的HR找到了我,我看了一下这家公司的业务,是我以前做过的基金与证券。还是很感兴趣的,决定去面试看看情况。 (因为只是想去涨面试经验,没有想拿offer,一些回答有点不太对,为后面木有offer埋下伏笔。其实有点亏,毕竟走路过去,而且还花了3个小时) 地点在金证股份科技大楼8楼。 2月25号 主要分为笔试题和面试。 1、笔试题 进来的时候直接给我一份笔试题做,做了一个半小时吧。 分为3道选择题和1道SQL查询题、1道案例设计题 选择题都是考察SQL函数,可能日常生活中没有见过

全村的希望的博客 4451

普通hash和一致性hash的区别

普通hash 定义 Hash函数:一般翻译做散列、杂凑,或音译为哈希,是把任意长度的输入(又叫做预映射pre-image)通过散列算法变换成固定长度的输出,该输出就是散列值。 碰撞(冲突):如果两个关键字通过hash函数得到的值是一样的,就是碰撞或冲突。 Hash表(散列表):根据散列函数和冲突处理将一组关键字分配在连续的地址空间内,并以散列值记录在表中的存储位置,这种表成为散列表。 常用...

weixin_41175789的博客 3839

华三模拟器实战:3分钟搞定路由器DHCP地址池配置(附常见错误排查)

本文提供华三模拟器中路由器DHCP地址池的实战配置指南。通过分步详解,帮助用户在3分钟内完成基础设置,并深入讲解多地址池、中继配置等进阶应用。文章重点剖析了DHCP服务无法工作的常见原因,提供从客户端到服务器的系统性排错方法,助力快速定位并解决地址分配失败、获取参数错误等典型问题。

w1x2y3的博客 361

一致性哈希算法的原理与实现

分布式系统中对象与节点的映射关系,传统方案是使用对象的哈希值,对节点个数取模,再映射到相应编号的节点,这种方案在节点个数变动时,绝大多数对象的映射关系会失效而需要迁移;而一致性哈希算法中,当节点个数变动时,映射关系失效的对象非常少,迁移成本也非常小。本文总结了一致性哈希的算法原理和Java实现,并列举了其应用。 作者:王克锋 出处:https://kefeng.wang/2018/08/1...

kefeng.wang 的博客 5万+

stm32f103c8t6+esp8266在WiFi下通过手机控制外设

stm32f103c8t6+esp8266在WiFi下通过手机控制外设前言 前言 通过上一篇,介绍了esp8266的基本功能,这篇将用stm32c8t6配合esp8266进行数据交互,实现用手机通过无线的方式去控制外设、开关等;这里相当于把stm32作为上一篇的串口助手和esp8266进行通信; ...

weixin_45430735的博客 1万+

保姆级教程:不用看古早代码,5分钟搞懂泛微ecology9附件存储与接口调用

本文详细解析了泛微ecology9附件存储与接口调用的核心原理,提供从基础概念到实战操作的完整指南。通过拆解文档化附件设计理念、解析RESTful接口参数,并给出Python代码示例,帮助开发者快速掌握附件上传与业务集成的关键技巧,提升二次开发效率。

weixin_28688385的博客 352

三分钟看懂一致性哈希算法

受一篇“五分钟看懂”的启发,来个哗众取宠的标题 一致性哈希算法,作为分布式计算的数据分配参考,比传统的取模,划段都好很多。 在电信计费中,可以作为多台消息接口机和在线计费主机的分配算法,根据session_id来分配,这样当计费主机动态伸缩的时候,因为session_id缓存缺失而需要放通的会话,会明显减少。 传统的取模方式 例如10条数据,3个节点,如果按照取模的方式,那就是

gerryke的blog 4万+

安卓刷Windows太难?这款手机平板双系统刷机工具,小白也能轻松拿捏!(小白福音!手机平板专用,一键搞定安卓刷 Windows 双系统!)

安卓刷Windows太难?这款手机平板双系统刷机工具,小白也能轻松拿捏!(小白福音!手机平板专用,一键搞定安卓刷 Windows 双系统!)

XiaoqiangClub的博客 4684
上一篇: 我同事说我写代码像写诗
下一篇: 折腾了2款虎年红包封面,开抢!
Java思维导图
博客等级 码龄10年 306粉丝 71原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值