继续我们的旅程,前几篇中,我们已经对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的学习到此就告一段落了。希望本系列的文章对读者们有帮助,谢谢。