LVS是Linux Virtual Server的简写,意即Linux虚拟服务器,是一个虚拟的服务器集群系统。本项目在1998年5月由章文嵩博士成立,是中国国内最早出现的自由软件项目之一。


LVS为了在不同场景中使用而提供了4种实现模型: 分别为
    NAT         -m 
    DR          -g 
    Tunnel      -i 
    FULLNAT     -b 
   
LVS的用到几个IP缩写
    CIP: 用户的IP
    VIP: LVS虚拟的IP,用于用户访问
    DIP: LVS Director调度器自已的IP
    RID: Real server 的IP
    LIP: LVS Director调度器指定的local address,FULLNAT模式下专用的


NAT模型工作流程
    1、客户端请求VIP(Virtual IP Address)
    2、Director接受到请求, 根据连接调度算法从一组真实服务器中选出一台服务器, 将报文的目标地址VIP(Virtual IP Address)改写成选定服务器的地址,报文的目标端口改写成选定服务器的相应端口,最后将修改后的报文发送给选出的服务器。
    3、调度器在连接Hash 表中记录这个连接,当这个连接的下一个报文到达时,从连接Hash表中可以得 到原选定服务器的地址和端口,进行同样的改写操作,并将报文传给原选定的服务 器。当来自真实服务器的响应报文经过调度器时,调度器将报文的源地址和源端口改为Virtual IP Address和相应的端口,再把报文发给用户

    不同的报文会使得连接处于不同的状态,不同的状态有不同的超时值。在TCP 连接中,根据标准的TCP有限状态机进行状态迁移;在UDP中,只设置一个UDP状态。
不同状态的超时值是可以设置的,在缺省情况下:
    SYN状态的超 时为1分钟
    ESTABLISHED状态的超时为15分钟
    FIN状态的超时为1分钟
    UDP状态的超时为5分钟
    当连接终止或超时,调度器将这个连接从 连接Hash表中删除。

实现NAT模型有几点需要注意的:
    1、RS和Director可以不在同一IP网段中
    2、可以实现端口映射
    3、请求报文和响应报文都必须经过Director
   
    在一些网络服务中,它们将IP地址或者端口号在报文的数据中传送,若只对报文头的IP地址和端口号作转换,这样就会出现不一致性,服务会中断。 所以,针对这些服务,需要编写相应的应用模块来转换报文数据中的IP地址或者端口号。现已经知道有这个问题的网络服务有FTP、IRC、H.323、 CUSeeMe、Real Audio、Real Video、Vxtreme/Vosiac、VDOLive、VIVOActive、True Speech、RSTP、PPTP、StreamWorks、NTT AudioLink、NTT SoftwareVision、Yamaha MIDPlug、iChat Pager、Quake和Diablo。


DR模型工作流程
    1、客户端请求VIP
    2、Director接收到请求报文,不修改也不封装IP报文,而是将数据帧的MAC地址改为选出服务器的 MAC地址,再将修改后的数据帧在与服务器组的局域网上发送。因为数据帧的MAC地址是选出的服务器,所以交换机会将数据帧发送给选出的服务器,服务器从中可以获得该IP报文。
    3、RIP接收到DIP发过来的报文后,发现报文的目标地址VIP是在本地的网络设备上,服务器处理这个报文,然后根据路由表将响应报文直接返回给客户。

因为VIP分别存在于Director和RS,造成IP冲突,解决方法:
    1、网络设备中设置VIP地址和DIrector的MAC地址进行绑定
    2、Linux系统中有一个软件可以实现对ARP广播进行过滤, arptables
    3、可以修改内核参数来实现, arp_ignore, arp_announce

实现DR模型需要注意的:
    1、RS和Director必须要在同一个二层网段中,中间没有隔有路由器(MAC地址无法穿越三层设备)
    2、请求报文必须经过Director, 但是响应报文一定不能通过Director
    3、不能实现端口映射


三种IP负载均衡技术的优缺点归纳在下表中:
                    VS/NAT          VS/TUN          VS/DR
Server              any             Tunneling       Non-arp device
server network      private         LAN/WAN         LAN
server number       low (10~20)     High (100)      High (100)
server gateway      load balancer   own router      Own router

以上三种方法所能支持最大服务器数目的估计是假设调度器使用100M网卡,调度器的硬件配置与后端服务器的硬件配置相同,而且是对一般Web服 务。使用更高的硬件配置(如千兆网卡和更快的处理器)作为调度器,调度器所能调度的服务器数量会相应增加。当应用不同时,服务器的数目也会相应地改变。所 以,以上数据估计主要是为三种方法的伸缩性进行量化比较。
   

FULLNAT工作流程
    1、引入LIP(local address),可以配置多个,也可以使用DIP
    2、客户端请求VIP
    3、Director接受到请求,根据调度算法得出转发的RS, 将CIP修改为LIP, VIP修改为对应RIP, 转发给RS
    4、RS接受到请求后, 响应请求给LIP, Director将响应报文RIP改为VIP, LIP改为CIP, 响应给用户
   
实现FULLNAT模型需要注意的:
    1、请求报文和响应报都要通过Director
    2、RIP接收到的请求报文的源地址为LIP,目标地址为RIP
    3、支持端口映射
    4、为了保证应用透明性,通过tcp option传递client ip给RealServer(TOA).要RS读取数据包中的tcp option来记录client ip
    5、和NAT比,正常转发性能下降<10%


LVS的调度算法

    IPVS在内核中的负载均衡调度是以连接为粒度的。在HTTP协议(非持久)中,每个对象从WEB服务器上获取都需要建立一个TCP连接,同一用户 的不同请求会被调度到不同的服务器上,所以这种细粒度的调度在一定程度上可以避免单个用户访问的突发性引起服务器间的负载不平衡。

    RR:Round Robin, 轮询 将用户请求轮询到各个RS上
    WRR: Weighted Round Robin, 加权轮轮询, 根据每一台RS的权重将用户请求轮询分发到各个RS上
    SH: Source Hash, 源地址哈希, 将同一客户端的请求转发到同一个RS上
    DH: Destination Hash, 将同一类型的请求转发到同一个RS上

    LC:least connections, 最小连接. 公式: Active*256+Inactive
    WLC:Weighted Least Connections, 加权最小连接. 公式: (Active*256+Inactive)/Weighted
    SED:Shortest Expection Delay, 最短延迟预期. 公式: (Active+1)*256/Weighted
    NQ:Never Queue, 永不排队, 对sed算法的改进
    LBLC:Locality-Based Least-Connections, 基于局部的最少链接, 即为动态的dh算法
    LBLCR:locality-based least-connections replication, 带复制功能的lblc


Hash表
    LVS的调优建议将hash table的值设置为不低于并发连接数。例如,并发连接数为200,Persistent时间为200S,那么hash桶的个数应设置为尽可能接近200x200=40000,2的15次方为32768就可以了。当ip_vs_conn_tab_bits=20 时,哈希表的的大小(条目)为 pow(2,20),即 1048576,对于64位系统,IPVS占用大概16M内存,可以通过demsg看到:IPVS: Connection hash table configured (size=1048576, memory=16384Kbytes)。对于现在的服务器来说,这样的内存占用不是问题。所以直接设置为20即可。

    关于最大“连接数限制”:这里的hash桶的个数,并不是LVS最大连接数限制。LVS使用哈希链表解决“哈希冲突”,当连接数大于这个值时,必然会出现哈稀冲突,会(稍微)降低性能,但是并不对在功能上对LVS造成影响。

    关于连接占用内存:
每条记录用一个ip_vs_conn结构表示,这个结构使用了Linux里面的典型数据结构struct list_head构造双向链表,使得所有的记录以链表形式链接起来。
* struct ip_vs_conn 里面的其他元素就是每个连接的具体信息,在32位系统上为128字节,64位系统上为192字节 。
* struct list_head 在32位系统上为8字节,在64位系统上为16字节。
    所以,hash表里面的每条记录(每个连接),在32位系统上占据136字节内存,在64位系统上占用208字节。


调整 ip_vs_conn_tab_bits的方法

ipvsadm -l

如果显示IP Virtual Server version 1.2.1 (size=4096),则ip_vs conn_tab_bits为默认的12

在/etc/modprobe.d/目录下添加文件ip_vs.conf,内容为:

options ip_vs conn_tab_bits=20
modprobe -r ip_vs
modprobe ip_vs

重新查看
IP Virtual Server version 1.2.1 (size=1048576)

假如没有变化,则需要重新调内核整编译选项,重新编译内核。


参考:
http://zh.linuxvirtualserver.org/node/2580
http://zh.linuxvirtualserver.org/files/LVS%E6%89%8B%E5%86%8C%E4%B8%AD%E6%96%87%E5%8A%A0%E7%9B%AE%E5%BD%95%E7%89%88.doc