理解分布式系统常用的负载均衡算法

拈花ヽ惹草 提交于 2019-11-27 22:48:15

分布式系统常用的负载均衡算法

最近在做的系统上使用ES比较多,出于对ES的学习,在了解了ES的负载均衡算法之后,也相应的了解了其它的负载均衡算法,在这里做一个分享。

1:轮询法:

轮询很容易实现,将请求按顺序轮流分配到后台服务器上,均衡的对待每一台服务器,而不关心服务器实际的连接数和当前的系统负载。使用轮询策略的目的是,希望做到请求转移的绝对均衡,但付出的性能代价也是相当大的。为了保证pos变量的并发互斥,引入了重量级悲观锁synchronized,将会导致该轮询代码的并发吞吐量明显下降。

2:随机法:

通过系统随机函数,根据后台服务器列表的大小值来随机选取其中一台进行访问。由概率统计理论得知,随着调用量的增大,其实际效果越来越仅仅与平均分配流量到后台的每一台服务器,也就是轮询法的效果。

3:随机轮询法:

随机轮询,就是将随机法和轮询法结合起来,在轮询节点时,随机选择一个节点作为开始位置的index,此后每次选择下一个节点来处理请求,即(index+1)%size。
这种方式只是在选择第一个节点使用了随机方法,其他与轮询法无异,缺点和轮询一样。

4:源地址哈希法:

源地址哈希的思想是根据服务消费者请求客户端的IP地址,通过哈希函数计算得到一个哈希值,将此哈希值和服务器列表的大小进行取模运算,得到的结果便是要访问的服务器地址的序号。采用源地址哈希法进行负载均衡,相同的ip客户端,如果服务器列表不变,将映射到同一个后台服务器进行访问。该方法适合访问缓存系统。
算法描述
假设有N台服务器,算法可以描述为:
1.通过指定的哈希函数,计算请求来源的地址的哈希值
2.对哈希值进行取模,底数为N
3.将余数作为索引值,从服务器列表中获取对应的服务器
假设我们现在有四台服务器:
在这里插入图片描述
源地址哈希法与权重没有关系,只与源地址有关。
优点:
源地址哈希法可以保证,只要请求源地址不变,总会请求到相同的目标服务器。
缺点:
1.由于用户的活跃度不同,可能会有大量的活跃用户被哈希到相同的服务器上,造成该服务器特别繁忙,大量的非活跃用户被哈希到相同的服务器上,造成该服务器几乎没有请求,造成请求不均衡。
2.一旦某个服务器挂掉,那么哈希到该服务器的所有请求都会失败,直到服务器恢复或者服务器列表中去掉该服务器。
试想如果分布式系统中在session中存储了用户的令牌信息,那么源地址哈希法就能解决这种存储方式下的一些个弊端(比如网站做免登,记录用户状态等等)

5:一致哈希算法:

一致哈希算法常用于负载均衡中要求资源被均匀的分布到所有节点上,并且对资源的请求能快速路由到对应的节点上。
1.MemCache集群,要求存储各种数据均匀的存到集群中各个节点上,访问这些数据时能快速的路由到集群中对应存放该数据的节点上;并且要求增删节点对整个集群影响很小,不至于有大的动荡造成整体负载的不稳定。
2.RPC过程中服务提供者做N个节点的集群部署,为了能在服务上维护一些业务状态,希望同一种请求每次都落到同一台服务器上。
具体算法过程为:
构造一个长度为02^32的整数环,根据节点名称的Hash值(其分布范围同样为02^32) 将缓存服务器节点放置在这个Hash环上。根据需要缓存的数据的Key值计算得到其Hash值(其分布范围同样为0~2^32),然后在Hash环上顺时针查找距离这个Key的Hash值最近的服务器节点,完成Key到服务器的Hash映射查找。
新加入的节点只影响整个环中的一小段。
具体应用中,长度为2^32的一致性Hash环通常使用二叉查找树实现,Hash查找过程实际上是在二叉查找树中查找不小于查找数的最小数值。当然这个二叉树最右边叶子节点和最左边的叶子节点相连接,构成环。
缺点:加入新节点的负载压力比其他节点压力小。
解决方案:增加一个虚拟层来解决,将每台物理服务器虚拟为一组虚拟服务器,将虚拟服务器的Hash值放到Hash环上,Key在环上先找到虚拟服务器节点,在得到物理服务器的信息。
效果:新加入物理服务器节点的时候,是将一组虚拟节点加入环中,如果虚拟节点的数目足够多,这组虚拟节点将会影响同样多数目的已经在环上存在的虚拟节点。新加入一台服务器将会较为均匀地影响原来集群中已经存在的所有服务器,即分摊原有缓存服务器集群中所有服务器的一小部分负载。
实践:虚拟节点太多影响性能,太少会导致负载不均衡。

6:加权轮询法:

不同的后台服务器可能机器的配置和当前系统的负载并不相同,因此他们的抗压能力也不一样。跟配置高,负载低的机器分配更高的权重,使其能处理更多的请求,而配置低,负载高的机器,则给其分配较低的权重,降低其系统负载,加权轮询很好的处理了这一问题,并将请求按照顺序且根据权重分配给后端。Nginx的负载均衡默认算法是加权轮询算法。
Nginx负载均衡算法简介
有三个节点{a, b, c},他们的权重分别是{a=5, b=1, c=1}。发送7次请求,a会被分配5次,b会被分配1次,c会被分配1次。
一般的算法可能是:
1、轮询所有节点,找到一个最大权重节点;
2、选中的节点权重-1;
3、直到减到0,恢复该节点原始权重,继续轮询;
这样的算法看起来简单,最终效果是:{a, a, a, a, a, b, c},即前5次可能选中的都是a,这可能造成权重大的服务器造成过大压力的同时,小权重服务器还很闲。
Nginx的加权轮询算法将保持选择的平滑性,希望达到的效果可能是{a, b, a, a, c, a, a},即尽可能均匀的分摊节点,节点分配不再是连续的。
Nginx加权轮询算法
1、概念解释,每个节点有三个权重变量,分别是:
(1) weight: 约定权重,即在配置文件或初始化时约定好的每个节点的权重。
(2) effectiveWeight: 有效权重,初始化为weight。
在通讯过程中发现节点异常,则-1;
之后再次选取本节点,调用成功一次则+1,直达恢复到weight;
此变量的作用主要是节点异常,降低其权重。
(3) currentWeight: 节点当前权重,初始化为0。
2、算法逻辑
(1) 轮询所有节点,计算当前状态下所有节点的effectiveWeight之和totalWeight;
(2) currentWeight = currentWeight + effectiveWeight; 选出所有节点中currentWeight中最大的一个节点作为选中节点;
(3) 选中节点的currentWeight = currentWeight - totalWeight;

这个算法的详细描述呢就是:比如有三台服务器,每台服务器权重不一样,首先选中权重最高的那一台处理请求,然后给它的权重减去三台服务器权重的和,这样第一次请求就来了,在处理第一次请求后,三台服务器的权重再分别加上它的默认权重,这样经过三台服务器权重之和的请求之后,又恢复到了默认权重上了,Nginx的负载均衡的算法的好处就是:均匀的分散了所有的请求,使它们错落有致。

6:加权随机法:

加权随机跟加权轮询类似,根据后台服务器不同的配置和负载情况,配置不同的权重。不同的是,它是按照权重来随机选取服务器的,而非顺序。

7:最小连接数法:

最小连接数法比较灵活和智能,由于后台服务器的配置不尽相同,对请求的处理有快有慢,它正是根据后端服务器当前的连接情况,动态的选取其中当前积压连接数最少的一台服务器来处理当前请求,尽可能的提高后台服务器利用率,将负载合理的分流到每一台服务器。
可能由于集群里各个服务器的配置不同,这种算法会导致大量的请求落到性能比较高的服务器上。

8:P2C算法:

随机选取两个节点,在这两个节点中选择延迟低,或者连接数小的节点处理请求,这样兼顾了随机性,又兼顾了机器的性能。
这些算法,理解起来都相对的简单,但是要正儿八经的实现,需要一定的基础功底。绝大多数情况下,我们都是使用的各种配置,来实现以上不同的算法。

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!