浅析lvs的十种负载调度算法

写在前面的话——

老师简单说了下云计算相关的东西,到了lvs的时候,下课了,干脆就布置作业自己写论文来介绍一下十种方法吧,然而实话实说,我确实没听懂整堂课,对自己失望一分钟!

百度了资料,相关信息还是很多的,老师要求不要太多,2000字不到3000字就可以了,然后我把我想复制过去的全部完了后,发现4500左右字了,又不想删掉,所以贴这了,实际论文我会删去算法流程的介绍部分,貌似就满足要求了!

本文参考了http://lzysg172.blog.51cto.com/6624306/1199412

还有http://chqz1987.blog.163.com/blog/static/51438311201272804410941/

最大的帮助应该是这个网站http://zh.linuxvirtualserver.org/node/35,几乎所有的算法流程都是复制的这里!

其实也有别的,不过在这两篇中差不多都能找到,就不贴了


参考了一篇论文,

基于LVS集群技术和动态反馈分组加权轮叫调度算法的SAMC—CDN网络系统研究

作者

黄建设

摘要

随着Internet的飞速发展和其对人们生活的深入影响,越来 越多的个人在互联网上购物、娱乐、休闲、与人沟通、获取信息;越来越多的企业把他们与顾客和业务伙伴之间的联络...

出版源

《现代电子技术》, 2008, 31(8):141-143


主要是参考了里面的关于加权轮叫调度的定义和算法流程


浅析lvs的十种负载调度算法

 

一、LVS概念

LVS(Linux VirtualServer):Linux 虚拟服务器

     LVS是个负载均衡设备,它不提供任何服务,用户请求到这里的时候,它是将客户需求转发至后端真正提供服务的服务,所以说后端的服务称作real server。LVS分为两段,前一段称为ipvsadm(管理集群服务的命令行工具),后面一段叫做ipvs(内核模块)。

二、LVS十种调度算法

LVS的调度方法分为两种,一种是静态方法(4种),一种是动态方法(6种):

静态方法:仅根据算法本身实现调度;实现起点公平,不管服务器当前处理多少请求,分配的数量一致

动态方法:根据算法及后端RS当前的负载状况实现调度;不管以前分了多少,只看分配的结果是不是公平

2.1、静态调度算法

1、轮叫调度(Round-RobinScheduling)

轮叫调度算法就是以轮叫的方式依次将请求调度不同的服务器,即每次调度执行i = (i + 1) mod n,并选出第i台服务器。算法的优点是其简洁性,它无需记录当前所有连接的状态,所以它是一种无状态调度。

在系统实现时,我们引入了一个额外条件,当服务器的权值为零时,表示该服务器不可用而不被调度。这样做的目的是将服务器切出服务(如屏蔽服务器故障和系统维护),同时与其他加权算法保持一致。所以,算法要作相应的改动,它的算法流程如下:

假设有一组服务器S = {S0,S1, …, Sn-1},一个指示变量i表示上一次选择的服务器,W(Si)表示服务器Si的权值。变量i被初始化为n-1,其中n > 0。

 

j = i;

do {

j = (j + 1) mod n;

         if(W(Sj) > 0) {

         i= j;

         returnSi;

         }

  } while (j != i);

return NULL;

 

  轮叫调度算法假设所有服务器处理性能均相同,不管服务器的当前连接数和响应速度。该算法相对简单,不适用于服务器组中处理性能不一的情况,而且当请求服务时间变化比较大时,轮叫调度算法容易导致服务器间的负载不平衡。

  虽然Round-Robin DNS方法也是以轮叫调度的方式将一个域名解析到多个IP地址,但轮叫DNS方法的调度粒度是基于每个域名服务器的,域名服务器对域名解析的缓存会妨碍轮叫解析域名生效,这会导致服务器间负载的严重不平衡。这里,IPVS轮叫调度算法的粒度是基于每个连接的,同一用户的不同连接都会被调度到不同的服务器上,所以这种细粒度的轮叫调度要比DNS的轮叫调度优越很多。

 

2、加权轮叫调度(WeightedRound-Robin Scheduling)

加权轮叫调度算法就是以轮叫的方式同时考虑其目标服务器的综合负载权值等依次将请求调度不同的服务器,即每次调度执行i = (i + 1) mod n,并选出第i台服务器,再权衡该服务器的权值决定是否继续轮叫下一台服务器。

在系统实现时,可以引入一个额外条件,当服务器的权值为零时,表示该服务器不可用而不被调度。这样做的目的是将服务器切出服务(如果屏蔽服务器故障和系统维护)。如果所有的服务器都是不是负责相同的功能,或者服务器都在同一个局域网内,性能差别比较大时,就需要采用分组加权轮叫调度算法(Group Weighted Round-Robin Scheduling),既实现全局的服务器均衡,有可保持各组服务器的性能基本均衡。

 

加权轮叫调度算法流程:

 

假设有一组服务器S = {S0, S1, …, Sn-1},W(Si)表示服务器Si的权值,一个指示变量i表示上一次选择的服务器,指示变量cw表示当前调度的权值,max(S)表示集合S中所有服务器的最大权值,gcd(S)表示集合S中所有服务器权值的最大公约数。变量i初始化为-1,cw初始化为零。

 

while (true) {

i = (i + 1) mod n;

if (i == 0) {

cw = cw - gcd(S);

if (cw <= 0) {

cw = max(S);

if (cw == 0)

return NULL;

}

}

if (W(Si) >= cw)

return Si;

}

 

3、目标地址散列调度(DestinationHashing Scheduling)

目标地址散列调度算法先根据请求的目标IP地址,作为散列键(Hash Key)从静态分配的散列表找出对应的服务器,若该服务器是可用的且未超载,将请求发送到该服务器,否则返回空。该算法的流程如下:

 

假设有一组服务器S = {S0, S1, ..., Sn-1},W(Si)表示服务器Si的权值,C(Si)表示服务器Si的当前连接数。ServerNode[]是一个有256个桶(Bucket)的Hash表,一般来说服务器的数目会运小于256,当然表的大小也是可以调整的。

算法的初始化是将所有服务器顺序、循环地放置到ServerNode表中。若服务器的连接数目大于2倍的权值,则表示服务器已超载。

 

n =ServerNode[hashkey(dest_ip)];

if ((n is dead)OR

                     (W(n) == 0) OR

(C(n) > 2*W(n))) then

return NULL;

return n;

在实现时,我们采用素数乘法Hash函数,通过乘以素数使得散列键值尽可能地达到较均匀的分布。所采用的素数乘法Hash函数如下:

 

static inlineunsigned hashkey(unsigned int dest_ip)

{

           return (dest_ip* 2654435761UL) &HASH_TAB_MASK;

}

其中,2654435761UL是2到2^32 (4294967296)间接近于黄金分割的素数,

 (sqrt(5) - 1) / 2 =  0.618033989

 2654435761 / 4294967296 = 0.618033987

 

 

4、源地址散列调度(SourceHashing Scheduling)

       源地址散列调度算法根据请求的源IP地址,作为散列键(Hash Key)从静态分配的散列表找出对应的服务器,若该服务器是可用的且未超载,将请求发送到该服务器,否则返回空。它采用的散列函数与目标地址散列调度算法的相同。算法流程与目标地址散列调度算法的基本相似,就是将请求的目标IP地址换成请求的源IP地址。

 

 

2.2、动态调度算法

1、最小连接调度(Least-ConnectionScheduling)

最小连接调度算法是把新的连接请求分配到当前连接数最小的服务器。最小连接调度是一种动态调度算法,它通过服务器当前所活跃的连接数来估计服务器的负载情况。调度器需要记录各个服务器已建立连接的数目,当一个请求被调度到某台服务器,其连接数加1;当连接中止或超时,其连接数减一。

 

在系统实现时,我们也引入当服务器的权值为零时,表示该服务器不可用而不被调度,它的算法流程如下:

 

假设有一组服务器S = {S0, S1, ..., Sn-1},W(Si)表示服务器Si的权值,

C(Si)表示服务器Si的当前连接数。

 

for (m = 0; m < n; m++) {

       if(W(Sm) > 0) {

              for(i = m+1; i < n; i++) {

                     if(W(Si) <= 0)

                            continue;

                     if(C(Si) < C(Sm))

                            m= i;

              }

              returnSm;

       }

}

return NULL;

当各个服务器有相同的处理性能时,最小连接调度算法能把负载变化大的请求分布平滑到各个服务器上,所有处理时间比较长的请求不可能被发送到同一台服务器上。但是,当各个服务器的处理能力不同时,该算法并不理想,因为TCP连接处理请求后会进入TIME_WAIT状态,TCP的TIME_WAIT一般为2分钟,此时连接还占用服务器的资源,所以会出现这样情形,性能高的服务器已处理所收到的连接,连接处于TIME_WAIT状态,而性能低的服务器已经忙于处理所收到的连接,还不断地收到新的连接请求。

 

2、加权最小连接调度(WeightedLeast-Connection Scheduling)

加权最小连接调度(WeightedLeast-Connection Scheduling)算法是最小连接调度的超集,各个服务器用相应的权值表示其处理性能。服务器的缺省权值为1,系统管理员可以动态地设置服务器的权值。加权最小连接调度在调度新连接时尽可能使服务器的已建立连接数和其权值成比例。加权最小连接调度的算法流程如下:

 

假设有一组服务器S = {S0, S1, ..., Sn-1},W(Si)表示服务器Si的权值,C(Si)表示服务器Si的当前连接数。所有服务器当前连接数的总和为CSUM = ΣC(Si)  (i=0, 1, .. , n-1)。当前的新连接请求会被发送服务器Sm,当且仅当服务器Sm满足以下条件
    (C(Sm) / CSUM)/ W(Sm) = min { (C(Si)/ CSUM) / W(Si)}  (i=0, 1, . , n-1)

其中W(Si)不为零

因为CSUM在这一轮查找中是个常数,所以判断条件可以简化为
C(Sm) / W(Sm) = min { C(Si) / W(Si)} (i=0, 1, . , n-1)

其中W(Si)不为零

 

因为除法所需的CPU周期比乘法多,且在Linux内核中不允许浮点除法,服务器的

权值都大于零,所以判断条件C(Sm) / W(Sm) > C(Si) /W(Si) 可以进一步优化

为C(Sm)*W(Si) > C(Si)* W(Sm)。同时保证服务器的权值为零时,服务器不被调

度。所以,算法只要执行以下流程。

 

for (m = 0; m < n; m++) {

       if(W(Sm) > 0) {

              for(i = m+1; i < n; i++) {

                     if(C(Sm)*W(Si) > C(Si)*W(Sm))

                            m= i;

              }

              returnSm;

       }

}

return NULL;

 

 

3、基于局部性的最少连接(Locality-BasedLeast Connections Scheduling)

基于局部性的最少链接调度(以下简称为LBLC)算法是针对请求报文的目标IP地址的负载均衡调度,目前主要用于Cache集群系统,因为在Cache集群中客户请求报文的目标IP地址是变化的。这里假设任何后端服务器都可以处理任一请求,算法的设计目标是在服务器的负载基本平衡情况下,将相同目标IP地址的请求调度到同一台服务器,来提高各台服务器的访问局部性和主存Cache命中率,从而整个集群系统的处理能力。

 

LBLC调度算法先根据请求的目标IP地址找出该目标IP地址最近使用的服务器,若该服务器是可用的且没有超载,将请求发送到该服务器;若服务器不存在,或者该服务器超载且有服务器处于其一半的工作负载,则用“最少链接”的原则选出一个可用的服务器,将请求发送到该服务器。该算法的详细流程如下:

 

假设有一组服务器S = {S0, S1, ..., Sn-1},W(Si)表示服务器Si的权值,C(Si)表示服务器Si的当前连接数。ServerNode[dest_ip]是一个关联变量,表示目标IP地址所对应的服务器结点,一般来说它是通过Hash表实现的。WLC(S)表示在集合S中的加权最小连接服务器,即前面的加权最小连接调度。Now为当前系统时间。

 

if (ServerNode[dest_ip] is NULL) then {

       n= WLC(S);

       if(n is NULL) then return NULL;

       ServerNode[dest_ip].server= n;

} else {

       n= ServerNode[dest_ip].server;

       if((n is dead) OR

           (C(n) > W(n) AND

            there is a node m with C(m) < W(m)/2)))then {

              n= WLC(S);

              if(n is NULL) then return NULL;

              ServerNode[dest_ip].server= n;

       }

}

ServerNode[dest_ip].lastuse = Now;

return n;

此外,对关联变量ServerNode[dest_ip]要进行周期性的垃圾回收(Garbage Collection),将过期的目标IP地址到服务器关联项进行回收。过期的关联项是指哪些当前时间(实现时采用系统时钟节拍数jiffies)减去最近使用时间超过设定过期时间的关联项,系统缺省的设定过期时间为24小时。

 

4、带复制的基于局部性最少连接(Locality-Basedleast Connections with Recplication Scheduling)

带复制的基于局部性最少链接调度(以下简称为LBLCR)算法也是针对目标IP地址的负载均衡,目前主要用于Cache集群系统。它与LBLC算法的不同之处是它要维护从一个目标IP地址到一组服务器的映射,而LBLC算法维护从一个目标IP地址到一台服务器的映射。对于一个“热门”站点的服务请求,一台Cache 服务器可能会忙不过来处理这些请求。这时,LBLC调度算法会从所有的Cache服务器中按“最小连接”原则选出一台Cache服务器,映射该“热门”站点到这台Cache服务器,很快这台Cache服务器也会超载,就会重复上述过程选出新的Cache服务器。这样,可能会导致该“热门”站点的映像会出现在所有的Cache服务器上,降低了Cache服务器的使用效率。LBLCR调度算法将“热门”站点映射到一组Cache服务器(服务器集合),当该“热门”站点的请求负载增加时,会增加集合里的Cache服务器,来处理不断增长的负载;当该“热门”站点的请求负载降低时,会减少集合里的Cache服务器数目。这样,该“热门”站点的映像不太可能出现在所有的Cache服务器上,从而提供Cache集群系统的使用效率。

 

LBLCR算法先根据请求的目标IP地址找出该目标IP地址对应的服务器组;按“最小连接”原则从该服务器组中选出一台服务器,若服务器没有超载,将请求发送到该服务器;若服务器超载;则按“最小连接”原则从整个集群中选出一台服务器,将该服务器加入到服务器组中,将请求发送到该服务器。同时,当该服务器组有一段时间没有被修改,将最忙的服务器从服务器组中删除,以降低复制的程度。LBLCR调度算法的流程如下:

 

假设有一组服务器S = {S0, S1, ..., Sn-1},W(Si)表示服务器Si的权值,C(Si)表示服务器Si的当前连接数。ServerSet[dest_ip]是一个关联变量,表示目标IP地址所对应的服务器集合,一般来说它是通过Hash表实现的。WLC(S)表示在集合S中的加权最小连接服务器,即前面的加权最小连接调度;WGC(S)表示在集合S中的加权最大连接服务器。Now为当前系统时间,lastmod表示集合的最近修改时间,T为对集合进行调整的设定时间。

 

if (ServerSet[dest_ip] is NULL) then {

       n= WLC(S);

       if(n is NULL) then return NULL;

       addn into ServerSet[dest_ip];

} else {

       n= WLC(ServerSet[dest_ip]);

       if((n is NULL) OR

           (n is dead) OR

           (C(n) > W(n) AND

            there is a node m with C(m) < W(m)/2)))then {

              n= WLC(S);

              if(n is NULL) then return NULL;

              addn into ServerSet[dest_ip];

       }else

       if(|ServerSet[dest_ip]| > 1 AND

           Now - ServerSet[dest_ip].lastmod > T)then {

              m= WGC(ServerSet[dest_ip]);

              removem from ServerSet[dest_ip];

       }

}

ServerSet[dest_ip].lastuse = Now;

if (ServerSet[dest_ip] changed) then

       ServerSet[dest_ip].lastmod= Now;

return n;

 

此外,对关联变量ServerSet[dest_ip]也要进行周期性的垃圾回收(Garbage Collection),将过期的目标IP地址到服务器关联项进行回收。过期的关联项是指哪些当前时间(实现时采用系统时钟节拍数jiffies)减去最近使用时间(lastuse)超过设定过期时间的关联项,系统缺省的设定过期时间为24小时。

 

5、最短延迟调度(ShortestExpected Delay Scheduling)

       最短延迟调度算法在加权最小连接调度算法的基础上改进,Overhead = (ACTIVE+1)*256/加权,即(活动的连接数+1)*256/除以权重,举例:

ABC三台机器分别权重123 ,连接数也分别是123。那么如果使用加权最小连接调度算法的话一个新请求进入时它可能会分给ABC中的任意一个。使用最短延迟调度算法后会进行这样一个运算

A(1+1)/1

B(1+2)/2

C(1+3)/3

根据运算结果,把连接交给C 。

 

6、永不排队调度(NeverQueue Scheduling)

       顾名思义,永不排队调度算法无需队列,如果有台realserver的连接数=0就直接分配过去,不需要在进行最短延迟调度算法的运算。

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值