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

news2025/1/17 18:00:52

 一致性哈希问题

简介

一致性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.coloradmin.cn/o/1569245.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Java web第一次作业

1.学会用记事本编写jsp文件&#xff0c;并放进tomcat的相关目录下&#xff0c;运行。 源代码&#xff1a; <% page contentType"text/html;charsetUTF-8" language"java" %> <html> <head> <title>我的第一个JSP页面</ti…

视觉大模型--deter的深入理解

但对于transformer用于目标检测领域的开创性模型&#xff0c;该模型言简意赅&#xff0c;但是但从论文理解&#xff0c;有很多细节都不清楚&#xff0c;尤其是解码器的query和二分图匹配(Bipartite Matching)和匈牙利算法(Hungarian Algorithm)相关&#xff0c;本文将根据代码详…

我认识的Git-Git工作流

WorkFlow 的字面意思&#xff0c;工作流&#xff0c;即工作流程。工作流不涉及任何命令&#xff0c;因为它就是一个规则&#xff0c;完全由开发者自定义&#xff0c;并且自遵守。 集中式工作流 集中式工作流以中央仓库作为项目所有修改的单点实体。相比svn缺省的开发分支trunk…

基于深度学习的植物叶片病害识别系统(网页版+YOLOv8/v7/v6/v5代码+训练数据集)

摘要&#xff1a;本文深入研究了基于YOLOv8/v7/v6/v5的植物叶片病害识别系统&#xff0c;核心采用YOLOv8并整合了YOLOv7、YOLOv6、YOLOv5算法&#xff0c;进行性能指标对比&#xff1b;详述了国内外研究现状、数据集处理、算法原理、模型构建与训练代码&#xff0c;及基于Strea…

FA模型切换Stage模型配置文件的差异app和deviceConfig的切换

FA模型切换Stage模型配置文件的差异 FA模型应用在 config.json文件 中描述应用的基本信息&#xff0c;一个应用工程中可以创建多个Module&#xff0c;每个Module中都有一份config.json文件。config.json由app、deviceConfig和module三部分组成&#xff0c;app标签用于配置应用…

捷途山海T2预售正式开启,起售价18.49万元,品质与价值并存!

捷途汽车于4月2日宣布&#xff0c;旗下全新车型山海T2正式启动预售。新车预售价格区间为18.49万元-21.69万元。这款定位为“旅行越野超混SUV”的新车&#xff0c;以其独特的方盒子造型和强大的混动系统&#xff0c;吸引了众多消费者的关注。 山海T2是捷途山海系列的第二款产品&…

JS详解-函数柯里化

简介&#xff1a; 柯里化&#xff08;Currying&#xff09;是一种关于函数的高阶技术。柯里化是一种函数的转换&#xff0c;它是指将一个函数从可调用的 f(a, b, c) 转换为可调用的 f(a)(b)(c)。柯里化不会调用函数。它只是对函数进行转换。 举个例子&#xff1a; 已最简单的…

nvme协议学习总结

一、nvme命令 1 nvme在pcie基础上的协议&#xff0c;与PCIE配合&#xff0c;实现高效传输。 2 nvme命令主要分IO命令和admin命令。 3 一个NVME CMD执行流程&#xff1a; step1&#xff1a;host把cmd写入SQ queue中&#xff1b; step2&#xff1a;host远端更新Device&#x…

Unity commandbuffer

在渲染不透明物体和天空盒之后&#xff0c;当前图像被复制到一个临时渲染目标中&#xff0c;模糊并设置为全局着色器属性。然后在玻璃物体上的着色器对模糊的图像进行采样&#xff0c;基于法线贴图的UV坐标偏移来模拟折射。这类似于shader GrabPass所做的&#xff0c;除了你可以…

解密辛普森悖论:如何在数据分析中保持清醒头脑

解密辛普森悖论&#xff1a;如何在数据分析中保持清醒头脑 之前也参加fine Bi的 培训&#xff0c;学到了辛普森悖论&#xff0c;今天为大家介绍一下 文章目录 解密辛普森悖论&#xff1a;如何在数据分析中保持清醒头脑前言我们来举一个例子数据分析解释管理应用的启示 前言 什…

Game Framework框架Builder窗口展示不完全问题解决方案

Game Framework框架Builder窗口展示不完全问题解决方案 问题描述解决方法 问题描述 最近在使用&#xff08;研究&#xff09;GF框架进行AssetBundle打包的时候&#xff0c;打开Builder窗口时发现下面的打包按钮被遮挡了&#xff0c;而且也没有滑动条可以滑动。 上网搜了一圈也…

文字超出收起展开功能的实现(vue2)

1.编写展开收起组件 <template><div class"text-clamp"><div class"text" :style"{height}"><span v-if"isVisible" class"btn" click"toggle">{{isExpand ? 收起 : ... 展开}}</spa…

简约好用的TCPUDP小工具

csdn下载地址&#xff1a; https://download.csdn.net/download/a876106354/89077745

Echarts自定义折线图的节点与图标

文章目录 需求分析 需求 如图所示需要自定义节点的图标展示 分析 首先需要 symbol 属性添加引入 需要用到一个工具&#xff1a;http://tu.chacuo.net/imagetodataurl 这里是我的几个图片转出来的svg export const lineColors [#FF5360,#45CB85,#EEB902,#9CEC0F,#FF9562,#…

书生作业2

Task 1 生成200字以上的笑话&#xff0c;可以看到使用不同的提示词&#xff0c;会有不同的效果。 如果使用提示词“讲一个笑话.200字以上”&#xff0c; 会有偶发的输出较短的笑话的情况。 如果使用提示词“讲一个200字以上的笑话”时&#xff0c;结果相对稳定。 下载目前两种…

Collection与数据结构 Stack与Queue(一): 栈与Stack

1. 栈 1.1 概念 栈&#xff1a;一种特殊的线性表&#xff0c;其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一端称为栈顶&#xff0c;另一端称为栈底。栈中的数据元素遵守后进先出LIFO&#xff08;Last In First Out&#xff09;的原则。 压栈&…

STL常用容器(2)---vector容器

1.1 vector基本概念 功能&#xff1a; vector数据结构和数组非常相似&#xff0c;也称为单端数组 vector与普通数组区别&#xff1a; 不同之处在于数组是静态空间&#xff0c;而vector可以动态扩展 动态扩展&#xff1a; 并不是在原空间之后的续接的新空间&#xff0c;而…

腾讯云4核8G配置的服务器有哪些优惠?价格好不?

2024年腾讯云4核8G服务器租用优惠价格&#xff1a;轻量应用服务器4核8G12M带宽646元15个月&#xff0c;CVM云服务器S5实例优惠价格1437.24元买一年送3个月&#xff0c;腾讯云4核8G服务器活动页面 txybk.com/go/txy 活动链接打开如下图&#xff1a; 腾讯云4核8G服务器优惠价格 轻…

邀请媒体采访报道对企业宣传有何意义?

传媒如春雨&#xff0c;润物细无声的&#xff0c;大家好&#xff0c;我是51媒体网胡老师。 邀请媒体采访报道对企业宣传具有多重意义&#xff1a; 提升品牌知名度和曝光度&#xff1a;媒体是信息传播的重要渠道&#xff0c;通过媒体的报道&#xff0c;企业及其活动、产品能够…

SpringBoot整合Flowable/Activiti

SpringBoot版本: 2.0.1.RELEASE Flowable版本: 6.3.1 Activiti版本: 6.0.0 一.添加pom依赖 因为之前我整合的时候有报错关于sqlsession的错误,后面查询文章才发现flowable要排除掉mybatis,又没说具体排除哪一个,所以我这干脆全部排除了 <!-- Flowable dependencies -->…