继续我们的旅程,前几篇中,我们已经对LVS的三种默认负载均衡技术进行了讲解,本篇中,我们再讲解和补充一些其他知识,尽力完成本阶段的LVS负载均衡的学习。

    本篇中,我们将讲解:

      (1)、ipvsadm参数介绍

      (2)、几种均衡算法的简介

      (3)、第四种负载均衡模式FullNat的介绍 


     一、ipvsadm参数介绍

    ipvsadm有众多的参数,通过控制这些参数我们可以进行更多更细微的操控。

    由于这些参数列表网上有大把,所以我打算偷偷懒不在这里列举了,各位读者可自行百度搜索。(笑……)

  

    二、几种负载均衡算法的介绍

    调度器作为LVS的重要组成部分,它的调度算法更扮演这至关重要的角色。目前,LVS中主要有八大内核连接调度算法,下面我将为读者们抽取其中最常见的四种调度算法进行介绍(部分摘抄自相关手册),更多具体的内容读者们可以在LVS的用户手册中找到。

    (1)、Round Robin Scheduling(轮叫调度算法):早在前面几篇中,我们已经使用了该算法(ipvsadm -A -t 192.168.1.55:80 -s rr 这里的rr->round robin),它也是所有调度算法中最简洁的一个,这种轮叫算法就是单纯的对每台机器做轮询,这种轮叫算法通常比较适合多台配置差不多的真实服务器之间使用,其实现算法如下:

//摘抄自手册
//假设有一组服务器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;
        return Si;
    }
} while (j != i);
return NULL;

    (2)、Round Robin Scheduling(加权轮叫算法):使用参数为“wrr”,该算法可以解决多台真实服务器之间性能不一的情况,该算法会根据预设的权值自动的指派服务器,权值高的(服务器)会优先分配流量,其调度算法流程如下: 

//摘抄自手册
//假设有一组服务器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)、Least-Connection Scheduling(最小连接调度算法):使用参数为“lc”,由于ipvsadm内部维护了一张状态表,上面记录了当前的状态(包括连接数),新请求到达时,LVS将根据当前状态自动选择一个连接数最少的服务器进行分流,因此,该算法也是一种动态调度算法,其调度算法流程如下: 

//摘抄自手册
//假设有一组服务器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;
        }
        return Sm;
    }
}
return NULL;

     (4)、Weighted Least-Connection Scheduling(加权最小连接调度算法):使用参数为“wlc”,该算法是最小连接调度算法的一个子集,有点类似于“最小连接调度算法”+“加权轮叫算法”的结合体,其调度算法流程如下: 

//摘抄自手册
//假设有一组服务器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;
        }
        return Sm;
    }
}
return NULL;

  

    三、第四种的负载均衡模式FullNat

    无论你在LVS的官方手册还是各大的LVS帖子中,上面也只仅仅找到地址转换、IP隧道和直接路由三种负载均衡模式,几乎不会再找到任何关于除这三种模式以外的其他模式。然而,事实上,还有一种名为“FullNat”的负载均衡模式。它是由阿里内部开发的一种新的负载均衡模式,目前它被托管到了Github中(地址为:https://github.com/alibaba/LVS)。

    它的物理拓扑与LVS-Nat非常相似,但常规的Nat模式,只进行DNat,这规定了所有参与负载均衡的真实服务器必须处于一个网段之内,当然,这对于一般的企业来说这已经是足够的,但对于更大型的企业以及拥有复杂网络结构的企业,是不够的。FullNat则是在DNat的基础上增加了SNat,所有经过负载均衡服务器转发过来的数据包的源IP地址也会进行改写,这样数据包在内网中就可以穿透Vlan,形成一个复杂的内部网络结构。

    但同时它也有自己的缺点,那就是这种模式使用起来异常繁琐,网络上极其难找到相关资料,截至完成本文的撰写为止,我仍然无法把FullNat完成部署,希望后面能成功部署,届时我将写出一篇详细的文章介绍。这里就点到为止,不作深入。 


    好的,本系列,关于LVS的学习到此就告一段落了。希望本系列的文章对读者们有帮助,谢谢。

  [ Linux ]   [ LVS ]   [ 负载均衡 ]
知识共享许可协议 本作品由小蝶惊鸿创作,采用知识共享署名 4.0 国际许可协议进行许可,转载时请保留本文署名及链接。