LVS作为构建集群的一种负载均衡器,由章文嵩先生编写,是当今世界上公认的最强的负载均衡器;负载均衡器主要适用于主机之间的资源分配太过紧张,系统性能过低,使用负载均衡器可以有效的让多台主机一起分担访问资源的压力,由LVS调度器分配由客户端请求的资源到后端的真实服务器,而将资源交由哪一台服务器操作则是由调度器通过特定的算法去实现的;
集群的构建是为了去解决某一特定问题而逐步构建起来的网络架构,也许一开始集群只有一台主机作为http服务器,一台作为动态资源访问的php-fpm服务器,一台作为数据库存储的服务器,当网站资源访问量大了之后,单一的php-fpm服务器无法有效的提供服务时就需要增加php-fpm的服务器,事实上一般公司都不止一台的php-fpm服务器进行动态资源管理,而当多台php-fpm服务器存在时,客户端访问资源时,假如客户只是将资源进行了收藏,而这条记录保存在第一台php-fpm的服务器上,当客户第二次重新访问的时候,怎么让客户基于第一台php-fpm服务器进行后续的访问呢?毕竟如果访问的是其他的服务器就没有之前客户所收藏的记录了;解决访问记录的方式有很多种常见的有会话粘性,会话复制等,但这类型的方式有其局限性,当所访问的php-fpm服务器出现问题的话,数据记录就会消失,所以最好的办法就是指定一个session server,这个会话服务器也是需要冗余备份的,至于他与另一台备份的会话服务器之间是共享的还是复制的,则是视情况而定了;支持后端真实服务器的mysql server和前端的http服务器也是需要冗余备份的,至于设置几台也是视情况而定的了;毕竟不能让其因为当机的原因不能正常工作;而当http服务器扩展为多台的情况下,客户端如何去考虑两台以上的http服务器,客户端去访问哪一台http服务器?不可能让客户端记录多个域名分别访问的,这个时候调度器的概念就出来了,通过调度器的调度算法去访问后端的真实服务器;LVS的工作方式是四层路由的模式,去寻找指定的路径,根据指定的IP和端口去将数据报文调度转发至后端的某个Real Server上;至于选择哪个真实服务器,则根据调度算法的不同来看;
同iptables/netfilter一样,设置LVS的集群服务也分为ipvsadm/ipvs,ipvsadm作为用户空间的命令行工具,用于管理集群服务,而ipvs则作为内核空间的netfilter的INPUT钩子之上的框架,可以接收来自ipvsadm的管理命令;
LVS集群中的专业术语:
CIP:客户端IP地址;
AIP:虚拟服务器对外提供服务的IP地址;
DIP:虚拟服务对真实服务器提供服务的IP地址;
RIP:真实服务器的IP地址;
使用LVS的一般通信过程:客户端以CIP作为源地址向虚拟服务器VIP发送此次请求;使用DIP发送至后方的真实服务器的RIP;
CIP-->VIP-->DIP-->RIP
1.当用户向调度器发出请求报文,调度器会将请求报文发往内核空间;
2.请求报文会首先通过PREROUTING链验证目的IP是否是VIP,若是则放入请求报文;
3.请求报文通过INPUT链进行验证,因为ipvs是工作在INPUT链上,与INPUT链上的集群服务进行验证,如果通过验证,则强行更改目的IP地址VIP,将其更改为RIP,并发送给POSTROUTING;
4.POSTROUTING接收到报文后查看目的IP地址,知道是自己的后端的服务器IP地址,则发往指定的RIP;
LVS的集群类型及其优缺点:
lv-nat集群:
通过网络地址转换的方式实现虚拟服务器;随着IPv4的IP地址的日益紧张很多企业的网络都采用内部网络的方式构建集群;lv-nat的架构模式是客户端通过访问调度器,请求报文的源IP地址为CIP,目标IP地址为VIP,通过调度器的INPUT链中的调度算法指定目标RIP,进行目标IP地址的转换,如DNAT,去访问后端的服务器,调度器会在Hash中记录这个连接,当这个连接再次访问时,会从Hash中选定原连接访问的服务器及其IP地址;后端服务器构建响应报文,源IP地址为RIP,目的IP地址为CIP,通过指定的网关DIP进入调度器,并在调度器中转换源IP地址,将RIP换成客户端的CIP,发送给客户端;
在lv-nat中需要注意的是:
1.DIP与RIP需要在同一个网段中;
2.RIP的网关要指向DIP;
3.调度器的系统必须是Linux系统;
4.调度器容易成为性能瓶颈;
lv-tun集群:
通过IP隧道实现虚拟服务器;其中隧道都是静态建立的,隧道一端有一个IP地址,另一端也有唯一的IP地址。客户端发出的请求报文源IP为CIP,目的IP为VIP,在经过调度器后,添加了一个报文首部源IP为DIP,目的IP为RIP将要重新封装的报文发往使用调度算法挑选出来的后端RS上;RIP在构建响应报文之后直接发给目标客户端;lv-tun集群,其响应报文直接发给目标主机,不通过调度器,有效的节省了调度器的资源,负载调度器就可以处理大量的请求,如lv-nat模式那般的话调度器大概能处理十台真实服务器,而在lv-tun中就可以处理上百台服务器,系统吞吐量大大增加;lv-tun这种模式,而CIP,VIP,DI
P,RIP都应该是公有的IP地址;其不支持端口重定向,在RS真实服务器上,需要有RIP以及VIP的存在;
lv-dr集群:
通过直接路由实现的虚拟服务器;这里的直接路由意味着,只有请求报文通过调度器调度转发到真实服务器,而响应报文可以直接通过路由器转发给客户端;lv-dr集群,调度器与真实服务器都连接在同一个交换机上,这时调度器的VIP与DIP就必须在同一个端口上;DIP与RIP在同一个网段上;客户端访问VIP,通过一层层路由转发,到达指定调度器,这时,需要注意的是客户端访问调度器,再由调度器转发给真实服务器的整个过程其请求报文的源IP,目标IP都没有被转换,一直都是CIP与VIP,在客户端访问调度器的过程中变化的只有MAC地址,到达调度器时,请求报文的源MAC地址为交换机的MAC地址,目标MAC地址为调度器的MAC地址;这样的话,当请求报文到达调度器要进行转发的时候,其目标IP地址是如何定位的?这个时候我们只有RS的MAC地址,并没有其对应的目标IP地址RIP,转发自然失败,这个时候就需要我们设置真实服务器,在真实服务器的环回端口lo处设置VIP,这样就有了对应的目标IP地址,但这样有一个问题就是当请求报文发到交换机时,因为真实服务器也拥有VIP地址,所以交换机也会将请求报文转发给真实服务器的RIP端口,因为Linux的特殊情况,所以环回接口的VIP也会对这个请求作出响应;在这个时候我们就要启用内核中的两个参数了,一个是arp_announce,用于在新添加的真实服务器对网络的应答,添加服务器时,服务器会将自己所有信息通告给网络,让所有服务器记录,做自我介绍,下次找他就很方便了,而arp_announce就是让这个应答过程隐藏起来,限制所有加入网络中的主机发送声明;而arp_ignore则是用于在访问的目的IP地址不是本接口的地址时,不对该请求响应,忽略;这个时候请求报文便可以正常处理,而响应报文则需要先通过环回接口,设置一条不管什么请求都需要经过环回接口的路由,这个时候响应报文的源IP地址为VIP,再通过直接路由转发给客户端,同lv-tun一般,不通过调度器转发响应报文,大大提高了调度器的吞吐量;
LVS的调度算法:
静态调度算法:只根据调度算法本身指定真实服务器,不根据真实服务器的情况调度
RR:轮询,第一次的请求给第一台RS,第二个请求给第二台RS,因为每台RS处理的资源的量不一样,有些时间长,有些时间短,这就可能造成有些RS越来越繁忙,有些RS越来越空闲;
WRR:加权轮询,主要根据权重判断服务器的状态,多的少给,少的多给;但还是轮询,只是特例而已;
SH:源地址哈希,调度器将来自于同一个IP地址的请求始终发往后端第一次被挑中的RS;从而实现会话绑定;
DH:目的地址哈希,发往同一个目标地址的请求,始终发往后端第一次被挑中的RS,一般用于正向代理服务器集群;因为代理服务器中有服务器内容的缓存,访问速度加快;
动态调度算法:根据后端服务器的状态而做出的相应的变换;Overhead表示后端服务器的负载;根据后端服务器当前的活动连接和非活动连接数来实现请求的调度;
LC:最少连接数;根据后端服务器每个服务器的连接数多少进行判断,越少的则分配更多的资源;有两种连接方式,活动连接activeconnections与非活动连接inactiveconnections
LC的负载计算:overhead=(activeconnections*256+inactiveconnection)
注意:第一次调度时,因为各个RS上没有任何连接,所以按照在ipvsadm中配置的顺序自上而下进行分配;
WLC:最少连接数,但也根据权重判断;因为每台服务器的性能不同权重也就不同;
WLC计算方式:Overhead=(activeconnection*256+inactiveconnections)/weight
权重越大说明解决问题的能力越强,负载就越低,这样就可以分配更多的资源进行处理;
注意:第一次调度时,因为各个RS上没有任何连接,所以按照在ipvsadm中配置的顺序自上而下进行分配;权重在第一次调度时不发挥作用;
SED:最短期望延迟;
SED计算方式:Overhead=(activeconnections*256+1)/weight
SED可以在第一次调度时就分配1个连接,从而根据权重得出的负载大小来分配资源;但SED请求存在的缺陷是可能会一直将请求分配给权重大的那个服务器,而其他服务器则处于空闲状态;
NQ:改进版的SED算法,首次调度时根据后端RS的权重,每台服务器分配一个连接;不让任何一个服务器空闲,很好的解决了SED的缺陷;每台服务器至少一个连接;然后再按照SED算法调度;必然会保证后端每台RS至少有一个活动连接;
LBLC:Locality Based Least Connections,基于本地的最少连接,动态的DH算法;
LBLCR:LBLC with Replication,带有复制功能的LBLC;把所有后端服务器的内容互相复制,保证每台服务器中的内容一样;
本文转自 wujunqi1996 51CTO博客,原文链接:http://blog.51cto.com/12480612/1973569