一致性hash问题(负载均衡原理)

 一致性哈希问题

简介

一致性Hash是一种特殊的Hash算法,由于其均衡性、持久性的映射特点,被广泛的应用于负载均衡领域,如nginx和memcached都采用了一致性Hash来作为集群负载均衡的方案。

本文将介绍一致性Hash的基本思路,并讨论其在分布式缓存集群负载均衡中的应用。同时也会进行相应的代码测试来验证其算法特性,并给出和其他负载均衡方案的一些对比。

一致性Hash算法简介

在了解一致性Hash算法之前,先来讨论一下Hash本身的特点。普通的Hash函数最大的作用是散列,或者说是将一系列在形式上具有相似性质的数据,打散成随机的、均匀分布的数据。

比如,对字符串abc和abcd分别进行md5计算,得到的结果如下:

可以看到,两个在形式上非常相近的数据经过md5散列后,变成了完全随机的字符串。负载均衡正是利用这一特性,对于大量随机的请求或调用,通过一定形式的Hash将他们均匀的散列,从而实现压力的平均化。(当然,并不是只要使用了Hash就一定能够获得均匀的散列,后面会分析这一点。)

举个例子,如果我们给每个请求生成一个Key,只要使用一个非常简单的Hash算法Group = Key % N来实现请求的负载均衡,如下:

(如果将Key作为缓存的Key,对应的Group储存该Key的Value,就可以实现一个分布式的缓存系统,后文的具体例子都将基于这个场景)

不难发现,这样的Hash只要集群的数量N发生变化,之前的所有Hash映射就会全部失效。如果集群中的每个机器提供的服务没有差别,倒不会产生什么影响,但对于分布式缓存这样的系统而言,映射全部失效就意味着之前的缓存全部失效,后果将会是灾难性的。

一致性Hash通过构建环状的Hash空间代替线性Hash空间的方法解决了这个问题,如下图:

整个Hash空间被构建成一个首尾相接的环,使用一致性Hash时需要进行两次映射。

第一次,给每个节点(集群)计算Hash,然后记录它们的Hash值,这就是它们在环上的位置。

第二次,给每个Key计算Hash,然后沿着顺时针的方向找到环上的第一个节点,就是该Key储存对应的集群。

分析一下节点增加和删除时对负载均衡的影响,如下图:

可以看到,当节点被删除时,其余节点在环上的映射不会发生改变,只是原来打在对应节点上的Key现在会转移到顺时针方向的下一个节点上去。增加一个节点也是同样的,最终都只有少部分的Key发生了失效。不过发生节点变动后,整体系统的压力已经不是均衡的了,下文中提到的方法将会解决这个问题。

负载均衡的实现原理

        对于上面这种情况,当一个请求进来以后,就会找它顺时针最近的一个点(也就是一个服务器),由于hash的均匀性,每个请求被均匀的分布在每台服务器上。这就实现了负载均衡

        如果要添加一个服务器m4,比如说m2和m3之间添加一个服务器,m4现在要管m2到m4之间的数据,这段数据之前是由m3管理。因此,现在m4只需要向m3要这一段数据。这样一看,添加服务器数据迁移的代价很低!

        如果要删除一个服务器m4,也很简单,只需要把m4的数据交给顺时针离他最近的服务器m3。

问题与优化

最基本的一致性Hash算法直接应用于负载均衡系统,效果仍然是不理想的,存在诸多问题,下面就对这些问题进行逐个分析并寻求更好的解决方案。

数据倾斜

如果节点的数量很少,而hash环空间很大(一般是 0 ~ 2^32),直接进行一致性hash上去,大部分情况下节点在环上的位置会很不均匀(就是没法均分),挤在某个很小的区域。最终对分布式缓存造成的影响就是,集群的每个实例上储存的缓存数据量不一致,会发生严重的数据倾斜。

负载不均衡

当服务器数量很小的时候,比如说三台服务器。就算是均分在哈希环上了,当一旦添加或者删除一台服务器,立马就变得负载不均衡。就如上面的例子,m3、m4加起来才管理三分之一的数据。其他两台服务器各占三分之一。

缓存雪崩

如果每个节点在环上只有一个节点,那么可以想象,当某一集群从环中消失时,它原本所负责的任务将全部交由顺时针方向的下一个集群处理。例如,当group0退出时,它原本所负责的缓存将全部交给group1处理。这就意味着group1的访问压力会瞬间增大。设想一下,如果group1因为压力过大而崩溃,那么更大的压力又会向group2压过去,最终服务压力就像滚雪球一样越滚越大,最终导致雪崩。

引入虚拟节点

解决上述两个问题最好的办法就是扩展整个环上的节点数量,因此我们引入了虚拟节点的概念。一个实际节点将会映射多个虚拟节点,这样Hash环上的空间分割就会变得均匀。

同时,引入虚拟节点还会使得节点在Hash环上的顺序随机化,这意味着当一个真实节点失效退出后,它原来所承载的压力将会均匀地分散到其他节点上去。

如下图:

引入虚拟节点还有一个好处就是:可以根据服务器性能做负载均衡管理!比如说group1号服务器性能好,我就多给他分配一点虚拟节点,group3服务器性能差,我就少给他分配一点!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/591541.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

计算机网络:局域网的数据链路层

✨✨ 欢迎大家来访Srlua的博文(づ ̄3 ̄)づ╭❤~✨✨ 🌟🌟 欢迎各位亲爱的读者,感谢你们抽出宝贵的时间来阅读我的文章。 我是Srlua小谢,在这里我会分享我的知识和经验。&am…

将 Elasticsearch 向量数据库引入到数据上的 Azure OpenAI 服务(预览)

作者:来自 Elastic Aditya Tripathi Microsoft 和 Elastic 很高兴地宣布,全球下载次数最多的向量数据库 Elasticsearch 是公共预览版中 Azure OpenAI Service On Your Data 官方支持的向量存储和检索增强搜索技术。 这项突破性的功能使你能够利用 GPT-4 …

Java数据结构-队列

目录 1. 队列概念2. 模拟实现队列2.1 链式队列2.2 循环队列 3. 双端队列4. 队列的应用4.1 用队列实现栈4.2 用栈实现队列 1. 队列概念 队列是一种只能在一端进行插入数据操作,另一端进行删除数据操作的数据结构,插入数据的叫队尾,删除数据的…

matlab——基于三维激光扫描点云的树冠体积计算方法

目录 一、算法原理1、原理概述2、参考文献二、代码实现三、结果展示本文由CSDN点云侠原创,原文链接。如果你不是在点云侠的博客中看到该文章,那么此处便是不要脸的爬虫与GPT。 一、算法原理 1、原理概述 针对树冠形状不规则,树冠体积难以测量和计算的问题,提出一种基于三…

第二十二章 Maven

一、Maven 1. Maven 简介 Maven 是一个项目管理工具,可以对 Java 项目进行自动化的构建和依赖管理。Maven 在美国是一个口语化的词语,代表专家、内行的意思,约等于北京话中的老炮儿。有老炮儿在身边,项目经理可谓得心应手。 项…

北京哪位医生治疗糖尿病比较好?

糖尿病是一种常见的慢性疾病,主要是由于胰岛素分泌不足或利用障碍导致的以高血糖为特征的代谢性疾病。持续的高血糖和长期的代谢紊乱可能导致全身组织器官,特别是眼、肾、心血管及神经系统的损害和功能障碍。 北京崇文门医院朱学敏主任在糖尿病领域有有着…

Go 源码之 gin 框架

Go 源码之 gin 框架 go源码之gin - Jxy 博客 一、总结 gin.New()初始化一个实例:gin.engine,该实例实现了http.Handler接口。实现了ServeHTTP方法 注册路由、注册中间件,调用addRoute将路由和中间件注册到 methodTree 前缀树(节…

AcWing---转圈游戏---快速幂

太久没写快速幂了... 这是一道数学题orz,能看出来的话答案就是 ,但是很大,同时还要mod n,直接用快速幂即可。 快速幂模版: long long int power(long long int a,long long int b,long long int mod){long long int r…

安装Docker(CentOS)

Docker 分为 CE 和 EE 两大版本。CE 即社区版(免费,支持周期 7 个月),EE 即企业版,强调安全,付费使用,支持周期 24 个月。 Docker CE 分为 stable test 和 nightly 三个更新频道。 官方网站上…

第16章 网络编程

一 网络编程概述 Java是 Internet 上的语言,它从语言级上提供了对网络应用程序的支持,程序员能够很容易开发常见的网络应用程序。 Java提供的网络类库,可以实现无痛的网络连接,联网的底层细节被隐藏在 Java 的本机安装系统里&am…

scoped原理及使用

一、什么是scoped,为什么要用 在vue文件中的style标签上,有一个特殊的属性:scoped。 当一个style标签拥有scoped属性时,它的CSS样式就只能作用于当前的组件,通过该属性,可以使得组件之间的样式不互相污染。…

jsp中使用cookie+session实现自动登录功能

1、需求分析 在实际运用中的用户登陆网站中,多提供有记住密码和自动登陆等功能,方便同一用户短时间内不用再输入用户名和密码等繁琐信息可以快捷登陆。本案例将模拟用户自动登陆功能。 1.2、设计思路(实现原理) 创建login.html页面…