一、LVS是什么?

二、IPVS的工作原理

三、为什么要使用LVS?

四、LVS集群的专用术语

五、LVS集群的类型

六、LVS调度方法(LVS Scheduler)


一、LVS是什么?


LVS(Linux Virtual Server,Linux虚拟服务器)是由章文嵩开发的一款开源软件(遵循GPL协议)。LVS工作在layer 4,又称为四层路由/四层交换,能够根据请求报文的目标IP地址和目标PORT将其调度转发至后端的某台服务器上,调度转发是根据调度算法来进行的。


LVS由两部分组成,分别是工作在内核空间的ipvs框架和工作在用户空间的ipvsadm命令。ipvsadm是工作在用户空间的命令行工具,用于管理集群服务及集群服务上的Real Server(RS),而ipvs则是工作于内核上的netfilter的INPUT钩子上的程序,其功能是根据用户定义的集群实现对请求报文的转发。


LVS支持基于TCP、UDP、SCTP、AH、EST、AH_EST等协议进行调度。


二、IPVS的工作原理


上面提到,ipvs工作于内核空间中,而ipvsadm则是用户定义集群的接口,并将用户定义的策略送往ipvs,因此真正使策略生效的是工作在netfilter的INPUT钩子上的ipvs程序。以下主要介绍ipvs的工作原理,其原理图如下。

LVS工作原理

当前端调度器(Director)接收到发往本主机的请求时,首先进入PREROUTING链,经查看路由表发现,该请求的目标IP地址是本主机,因此将请求报文送往INPUT链,经过查看请求报文的目标端口发现,请求的是集群服务的端口,因此IPVS就会根据调度方法和集群类型,强行将请求报文发往FORWARD链上,而后经过POSTROUTING,再送往基于调度算法挑选出的某一台后端RS。


三、为什么要使用LVS?


LVS是负载均衡能力最强的一款软件,对于选择LVS作为负载均衡的原因总结如下。

1、相比于Nginx、Haproxy等负载均衡器,LVS支持较大的并发量。Nginx、Haproxy是工作在七层的负载均衡器,因此需要监听在一个端口上,同时对于每一个客户端都需要打开一个套接字文件来接受请求数据,当在应用层分析完数据时,有需要扮演成客户端角色向后端的服务器主机发送请求报文,不仅需要打开大量套接字文件,还需要有多个随机端口可以使用,而端口数最多只有65535个,并且其中有一部分端口是不能使用的。因此,工作在七层的负载均衡软件(如Nginx、Haproxy等)的最大并发数受限于能够打开的套接字文件数(内核需要打开很多的文件描述符来维护)以及能使用的随机端口数。对于LVS而言,因此它工作在四层,所以不需要监听在某个端口以响应客户端请求,因此不需要打开套接字接受和发送数据,同时也不需要使用端口,所有功能均在ipvs中实现,因此LVS的性能更高,支持的并发量更大。据统计,LVS的最大并发量可以达到400~500w。

2、LVS是一款开源且免费的软件,结合Linux使用可以大大降低企业的应用成本。

3、LVS具有可伸缩性。当一台服务器负载压力增长时,系统可以在不降低服务质量的情况下通过扩展来满足需求。

4、LVS具有高可靠性。这在国内很多大型的、关键性的Web站点实践中得到印证。


四、LVS集群的专用术语


VS:Virtual Server,虚拟服务器,又称调度器(Director)、分发器(Dispatcher)和负载均衡器(Balancer)。

RS:Real Server,真实服务器,即在调度器后端提供服务的服务器主机。

CIP:Clint IP,客户端的IP地址。

VIP:Virtual IP,调度器(Director)面向客户端提供服务的IP地址。

DIP:Director IP,调度器(Director)用于与后端真实服务器(RS)通信的IP地址。

RIP:Real server IP,调度器(Director)后端的真实服务器(RS)的IP地址。


五、LVS集群的类型


用户请求到达前端的负载调度器后,根据调度器如何将请求报文发送到各个提供服务的Real Server(RS)节点,以及各Real Server(RS)节点如何返回数据给用户,可以将LVS集群类型分为LVS-NAT、LVS-DR、LVS-TUN和LVS-FullNat四种。其中,LVS-NAT、LVS-DR和LVS-TUN是LVS的标准类型,而LVS-FullNat则为非LVS的标准类型,是根据淘宝的需要而改进的一种集群类型。以下分别介绍这四种集群类型。


1、LVS-NAT


NAT即Network Address Translation,也即是通过网络地址转换技术来实现虚拟服务器。在NAT方式中,当用户请求报文到达时,调度器通过将请求报文中的目标地址和目标端口修改为挑选出的某RS的RIP和PORT以实现转发。因此,LVS-NAT相当于多目标的NAT。RS得到数据后即开始处理请求,当RS将响应数据返回给用户时,需要再次经过调度器并由调度器将响应报文的源地址和源端口修改为调度器的VIP和相应的PORT,然后把数据发送给用户,完成整个负载调度的过程。

LVS工作原理


LVS-NAT模型的特性:

(1)DIP和RIP必须在同一IP网络中(因为响应报文要经由Director转发),且应该使用私有地址;各个RS的网关要指向DIP(保证响应报文经由VS)。

(2)请求报文和响应报文都经由Director转发,因此在较高负载下(用户请求越来越多时),Director易成为系统性能瓶颈。

(3)因为请求报文和响应报文都经由Director,因此支持端口映射。

(4)VS必须是Linux,RS可以是任意OS。


注意:因为LVS-NAT是多目标的NAT,因此需要打开连接追踪模板来追踪连接,最大并发数取决于连接追踪模板能够记录的连接数量,而链接追踪模板能够记录的连接数量则取决于用于记录连接追踪的内存空间大小。


2、LVS-TUN


TUN即Tunneling,也就是通过IP隧道技术实现虚拟服务器。在TUN方式中,当用户请求报文到达时,调度器不修改请求报文的IP首部(源IP为CIP,目标IP为VIP),而是在原IP首部之外再封装一个IP首部(源IP为DIP,目标IP为挑选出的RS的RIP)。而这个RS将直接响应用户的请求,不会再经由Director转发,因此调度器只处理用户的报文请求,从而大大提高了集群系统的吞吐量。LVS-TUN这种集群类型的另外一个特点是对RS的地域位置没有要求,一般和Director不再同一网段中(也可以在同一网段),即各个RS可以分别分布在不同的地域位置。

LVS工作原理


LVS-TUN模型的特性:

(1)RIP、VIP和DIP全得是公网地址。

(2)RS的网关不能指向也不可能指向DIP。

(3)请求报文经由Director转发,但响应报文将由RS直接发往CIP。

(4)因为响应报文不经由Director转发,因此不支持端口映射。

(5)RS的OS必须支持隧道功能。


问题1:使用LVS-TUN这种方式时,因为需要再添加IP首部,如果再封装一个IP首部后超过MTU怎么办?

回答:需要做分片处理。


问题:为什么DIP必须为公网地址?

回答:因为封装IP隧道(外IP首部)时,源IP为DIP,目标IP为RIP,这个具有两个IP首部的报文在出口时经由路由器但不可能进行NAT,否则报文的两个IP首部都可能会被拆掉,导致RS接受不到请求报文。


3、LVS-DR


DR即Direct Routing,也就是通过直接路由实现虚拟服务器。在DR方式中,当用户请求报文到达负载调度器时,调度器通过为请求报文重新封装一个MAC首部进行转发,重新封装后的报文中的源MAC是DIP所在接口的MAC地址,目标MAC是挑选出的某RS的RIP所在的接口的MAC地址,而请求报文的IP首部不会发生变化(源IP是CIP,目标IP是VIP)。而RS将响应直接返回给用户,可以免去LVS-TUN中的IP隧道开销。因此在LVS-NAT、LVS-TUN和LVS-DR这三种最常用的调度方式中,LVS-DR这种调度方式是性能最好的。在LVS-DR这种方式中,各个RS上都必须配有VIP,以便在响应用户请求时,用VIP作为源IP来封装报文的IP首部。

LVS工作原理


LVS-DR模型的特性:

(1)必须确保前端路由器将目标IP为VIP的请求报文发往Director。

解决方案:
1、在路由器上静态绑定VIP和Director的MAC地址。当这种方式有两点缺陷:
    (1)必须有前端路由器的控制权。
    (2)当构建高可用LVS负载均衡集群时,调度器的VIP所在接口的MAC地址可能会发生改变。
2、禁止RS响应VIP的ARP请求,禁止RS的VIP进行通告。
    (a)通过arptables命令设定。
    (b)修改RS的内核参数(arp_ignore, arp_announce),并把VIP绑定在lo的接口的别名上。

(2)RS的RIP可以使用私网地址,也可以使用公网地址。

(3)RS跟Director必须在同一物理网络中。否则,如果RS跟Director之间只要多了一个路由器则MAC地址就改变了,无法确保按照Director的调度将请求报文转发给挑选出的某RS。

(4)RS的网关必须不能指向DIP。

(5)请求报文必须由Director调度,但响应报文必须不能经由Director转发。

(6)因为响应报文必须不能经由Director转发,因此不支持端口映射。

(7)RS可以使用大多数OS。


4、LVS-FullNat


FullNat即完全网络地址转换,也即是通过完全网络地址转换技术来实现虚拟服务器的。在FullNat方式中,当用户请求报文到达时,调度器通过同时修改请求报文的源IP地址(CIP --> DIP)和目标IP地址(VIP --> RIP)进行转发。响应报文则相反。使用这种方式,可以构建一个更为复杂的内部网络,可以经过路由器转发请求报文,但又不至于像LVS-TUN一样需要在原来的IP首部之外再封装一个IP首部,从而可能造成巨型帧(有可能会超过MTU)。

LVS工作原理


FullNat模型的特性:

(1)VIP是公网地址,DIP和RIP是私网地址,且通常不在同一网络中,但需要经由路由器互通。

(2)RS收到的请求报文源IP为DIP,因此响应报文将直接响应给DIP。也就是请求报文和响应报文都经由Director。

(3)因为请求报文和响应报文都经由Director,所以支持端口映射。

(4)RS可以使用大多数的OS。


六、LVS调度方法(LVS Scheduler)


LVS的调度方法有多种,根据其调度时是否考虑后端主机的当前负载,可分为静态方法和动态方法两类。静态方法有RR、WRR、SH和DH,动态方法有LC、WLC、SED、NQ、LBLC和LBLCR。


6.1 静态方法


静态方法就是仅根据算法本身进行调度的算法。静态方法有RR、WRR、SH和DH这四种。接下来分别介绍每一种静态方法。

(1) RR

全称 ==> Round Robin,轮询/轮调/轮叫。

特点 ==> 调度器将用户请求分别轮询转发给各台RS。

缺陷 ==> 没有考虑到各RS的负载能力可能不同。


(2) WRR

全称 ==> Weighted RR,加权轮询。

特点 ==> 调度器将用户请求分别按照各RS的(事先设定好的)权重,轮询转发给各台RS,也就是给一定权重的RS分配与其权重匹配的用户请求报文数量。

优点 ==> 考虑了各RS的负载能力可能不同(通过权重值设定),弥补了RR算法的缺陷。


(3) SH

全称 ==> Source Hashing,源地址哈希。

特点 ==> 根据请求报文的源地址与此前挑选出的RS绑定起来,即实现将同一个IP的请求发往同一个RS,这是会话保持的一种方式。哈希的是源地址。SH算法是通过在内存中维护一个哈希表以实现绑定效果的。

适用场景 ==> 在电商站点中可能会用到SH算法。


(4) DH

全称 ==> Destination Hashing,目标地址哈希。

特点 ==> 根据请求报文的目标地址与某台RS绑定起来,即实现将目标地址为同一个地址的请求报文发往同一个RS。哈希的目标地址。DH算法是通过在内存中维护一个哈希表以实现绑定效果的。

适用场景 ==> 通常用在正向Web代理(缓存)服务器中,负载均衡内网用户对外部服务器的请求。调度器可根据客户端访问的目标地址将请求报文找到对应的缓存服务器,可以提高缓存命中率。


6.2 动态方法


动态方法就是根据算法仅各RS当前的负载状态进行调度的算法。各RS当前的负载值用“Overhead”进行表示。动态方法有LC、WLC、SED、NQ、LBLC和LBLCR等。在介绍动态方法之前,需要了解连接种类。连接分为活动连接(Active)和非活动连接(Inactive)两种,如下。

① 活动连接(Active):指的是服务器正在等待客户端发送请求的连接、服务器正在处理请求的连接或者服务器正在响应客户端请求的连接。每个活动连接消耗的资源比非活动连接多得多,相当于256个非活动连接。

② 非活动连接(Inactive):指的是处于空闲状态的连接,即在连接上没有传输数据。


接下来分别介绍每一种动态方法。

(1) LC

全称 ==> Least Connections,最少连接。

公式 ==> Overhead=Active*256+Inactive

特点 ==> 调度器将用户请求发往连接数最少(Overhead最少)的RS。

缺陷 ==> 没有考虑到各RS负载能力可能不同。


(2) WLC

全称 ==> Weighted LC,加权最少连接。

公式 ==> Overhead=(Active*256+Inactive)/weight

说明 ==> WLC是最通用的、默认的调度方法。

特点 ==> 调度器将用户请求发往加权连接数最少(Overhead最少)的RS。

优点 ==> 既考虑了各RS的连接数,又考虑了各RS的负载能力,弥补了LC算法的缺陷。

缺陷 ==> 刚开始所有RS都没有负载的情况下,Overhead都为0,因此在各RS的Overhead值都相等的情况下,调度器只能通过轮询的方法来调度转发,所以调度器可能会把第一个用户请求发往处理能力较低的RS。


(3) SED

全称 ==> Shortest Expections Delay,最小期望延迟。

公式 ==> Overhead=(Active+1)*256/weight

特点 ==> 不考虑非活动连接数,初始时活动连接数为1,调度器将用户请求发往加权连接数最少(Overhead最少)的RS。

优点 ==> 刚开始各RS零负载的情况下,Overhead不为0,调度器仍然会先把请求转发到负载能力(处理能力)较强的RS上,弥补了WLC算法的缺陷。

缺陷 ==> 在并发量不是很大时,有可能调度器会把所有的请求都发往负载能力较强的RS,导致负载能力较弱的RS一直处于空闲状态。而且SED算法不考虑非活动连接数,可能不适应于某些场景(非活动连接对性能影响较大时)。


(4) NQ

全称 ==> Never Queue,不排队。

特点 ==> 是RR算法和SED算法的结合,是SED算法的优化。在各RS零负载的情况下,调度器先将用户请求分别轮询转发给每一台RS(不管其负载能力/处理能力的高低),确保每一台RS都处理一定数量的请求,然后再按照SED算法进行调度。

优点 ==> 保证了各RS都处理一定数量的用户请求,因此继承了SED算法的优点,弥补了SED算法的缺陷。

缺陷 ==> 与SED一样不考虑非活动连接数,可能不适应于某些场景(非活动连接对性能影响较大时)。


(5) LBLC

全称 ==> Locality-Based LC,基于本地的LC算法。

特点 ==> 是动态的DH算法。与DH一样,其应用场景通常为正向Web代理(缓存)服务器,但相比于DH算法而言,LBLC是通过牺牲缓存的命中率来提高负载均衡的效果的。

优点 ==> 相比较于DH算法,经由调度器转发后能使用户请求报文更加负载均衡在多台缓存服务器上。

缺陷 ==> 虽然使用户请求更加负载均衡在多台缓存服务器上,但牺牲了缓存服务器的命中率。


(6) LBLCR

全称 ==> LBLC with Replcation,带复制功能的LBLC。

特点 & 优点 ==> 是改进版的LBLC算法,既考虑了负载均衡,又考虑了缓存的命中率。如果用户请求报文被调度到没有对应缓存资源的缓存服务器(正向代理)上时,则该缓存服务器可以直接到已有该缓存资源的缓存服务器上请求并获取资源,而不是到原始服务器上去请求。只有当所有缓存服务器上都没有该缓存资源时,才到原始服务器上去请求。