畅聊架构 2020-03-08
网站架构中,负载均衡技术是实现网站架构伸缩性的主要手段之一。所谓"伸缩性",是指可以不断向集群中添加新的服务器来提升性能、缓解不断增加的并发用户访问压力。通俗地讲,就是一头牛拉不动时,就用两头、三头、更多头牛来拉。
负载均衡有好几种方式:http URL重定向、DNS的A记录负载均衡、反向代理负载均衡、IP负载均衡和链路层负载。本文所述为LVS,它的VS/NAT和VS/TUN模式是IP负载均衡的优秀代表,而它的VS/DR模式则是链路层负载均衡的优秀代表。
LVS中文官方手册:http://www.linuxvirtualserver.org/zh/index.html。这个手册对于了解lvs的背景知识很有帮助。
LVS英文官方手册:http://www.linuxvirtualserver.org/Documents.html。这个手册比较全面,对于了解和学习lvs的原理、配置很有帮助。
LVS是章文嵩开发的一个国产开源负载均衡软件。LVS最初是他在大学期间的玩具,随着后来使用的用户越来越多,LVS也越来越完善,最终集成到了Linux的内核中。有不少开源牛人都为LVS开发过辅助工具和辅助组件,最出名的就是Alexandre为LVS编写的Keepalived,它最初专门用于监控LVS,后来加入了通过VRRP实现高可用的功能。
LVS的全称是Linux virtual server,即Linux虚拟服务器。之所以是虚拟服务器,是因为LVS自身是个负载均衡器(director),不直接处理请求,而是将请求转发至位于它后端真正的服务器realserver上。
LVS是四层(传输层tcp/udp)、七层(应用层)的负载均衡工具,只不过大众一般都使用它的四层负载均衡功能ipvs,而七层的内容分发负载工具ktcpvs(kernel tcp virtual server)不怎么完善,使用的人并不多。
ipvs是集成在内核中的框架,可以通过用户空间的程序ipvsadm
工具来管理,该工具可以定义一些规则来管理内核中的ipvs。就像iptables和netfilter的关系一样。
首先要解释的是LVS相关的几种IP:
VIP:virtual IP,LVS服务器上接收外网数据包的网卡IP地址。 DIP:director IP,LVS服务器上转发数据包到realserver的网卡IP地址。 RIP:realserver(常简称为RS)上接收Director转发数据包的IP,即提供服务的服务器IP。 CIP:客户端的IP。
LVS的三种工作模式:通过网络地址转换(NAT)将一组服务器构成一个高性能的、高可用的虚拟服务器,是VS/NAT技术。在分析VS/NAT的缺点和网络服务的非对称性的基础上,提出了通过IP隧道实现虚拟服务器的方法VS/TUN(Virtual Server via IP Tunneling),和通过直接路由实现虚拟服务器的方法VS/DR(Virtual Server via Direct Routing),它们可以极大地提高系统的伸缩性。
客户端发送的请求到达Director后,Director根据负载均衡算法改写目标地址为后端某个RIP(web服务器池中主机之一)并转发给该后端主机,就像NAT一样。当后端主机处理完请求后,后端主机将响应数据交给Director,并由director改写源地址为VIP后传输给客户端。大多数商品化的IP负载均衡硬件都是使用此方法,如Cisco的LocalDirector、F5的Big/IP。
这种模式下:
采用NAT技术时,由于请求和响应报文都必须经过调度器地址重写,当客户请求越来越多时,调度器的处理能力将成为瓶颈。为了解决这个问题,调度器把请求报文通过IP隧道转发至真实服务器,而真实服务器将响应直接返回给客户,所以调度器只处理请求报文。由于一般网络服务响应报文比请求报文大许多,采用VS/TUN技术后,调度器得到极大的解放,集群系统的最大吞吐量可以提高10倍。
VS/TUN模式的工作原理:
采用VS/TUN模式时的基本属性和要求:
一般来说,VS/TUN模式会用来负载调度缓存服务器组,这些缓存服务器一般放置在不同网络环境,可以就近返回数据给客户端。在请求对象不能在Cache服务器本地命中的情况下,Cache服务器要向源服务器发请求,将结果取回,最后将结果返回给客户。
VS/TUN模式下,调度器对数据包的处理是使用IP隧道技术进行二次封装。VS/DR模式和VS/TUN模式很类似,只不过调度器对数据包的处理是改写数据帧的目标MAC地址,通过链路层来负载均衡。
VS/DR通过改写请求报文的目标MAC地址,将请求发送到真实服务器,而真实服务器将响应直接返回给客户。同VS/TUN技术一样,VS/DR技术可极大地提高集群系统的伸缩性。这种方法没有IP隧道的开销,对集群中的真实服务器也没有必须支持IP隧道协议的要求,但是要求调度器与真实服务器都有一块网卡连在同一物理网段上,以便使用MAC地址通信转发数据包。
VS/DR模式的工作原理:
也就是说,客户端请求发送到LB上,源和目标IP为CIP:VIP,LB上有VIP和DIP,重新改写MAC地址后通过DIP发送给某个realserver,如RS1,此时源和目标IP还是CIP:VIP,但是目标MAC地址改写为RIP1所在网卡的MAC地址"RS1_MAC",RS1发现自身有VIP地址,所以收下此数据报文(所以在RS上必须配置VIP)。返回时,RS1根据路由表直接返回给客户端,此时,源和目标IP是VIP-->CIP。但由于流出接口为RIP所在网卡接口,因此源MAC地址为RIP所在接口的MAC地址。这一细节在考虑CIP、RIP不同网段时的配置时很重要。
采用VS/DR模式时的基本属性和要求:
三种模式的比较如图所示:
在性能上,VS/DR和VS/TUN远高于VS/NAT,因为调度器只处于从客户到服务器的半连接中,按照半连接的TCP有限状态机进行状态迁移,极大程度上减轻了调度器的压力(真正建立TCP连接的是RS和Client)。VS/DR性能又稍高于VS/TUN,因为少了隧道的开销。但是,VS/DR和VS/TUN的主要区别是VS/TUN可以跨网络实现后端服务器负载均衡(也可以局域网内),而VS/DR只能和director在局域网内进行负载均衡。
在应用负载均衡之LVS(二):VS_TUN和VS_DR的arp问题中非常详细地分析了ARP、arp_ignore和arp_announce相关原理和设置方法。此处简单说明为何需要设置arp抑制以及设置arp抑制的方法。
当一个目标IP地址为VIP的数据包进入Director前端的路由器时,路由器会向局域网内发送ARP广播,以找出VIP地址的MAC地址在哪台主机上。
Director和各RS都配置了VIP。当路由器发送ARP广播后,Director和RS都会收到这个广播包,且都认为这个广播包找的就是自己,于是都回应给路由器,这样路由器上的ARP缓存表中的条目VIP<-->vip_MAC
就不断被覆盖直到最后一个回应。这样一来,路由器将把客户端的数据包发送给最后一个回应的主机,这台主机的VIP可能是Director上的,也可能是某个RS上的。在一定时间内,路由器收到目标IP为VIP的数据包都会发送给该主机。但路由器会定时发送ARP广播包,这样一来ARP缓存表中的VIP对应的MAC地址可能会换成另一台主机。
因此,必须要保证路由器只保存Director上VIP对应的MAC地址,即只允许Director才对路由器的ARP广播进行回应。也就是说,所有RS上的VIP必须隐藏起来。
一般通过将Real Server上的VIP设置在lo接口的别名接口上(如lo:0),并设置arp_ignore=1
和arp_announce=2
的方式来隐藏RS上的VIP。至于VIP为何要设置在lo接口上以及为何要这样设置这两个arp参数,请参看应用负载均衡之LVS(二):VS_TUN和VS_DR的arp问题,内容非常详细。
echo 1 >/proc/sys/net/ipv4/conf/all/arp_ignore echo 2 >/proc/sys/net/ipv4/conf/all/arp_announce
或者
sysctl -w net.ipv4.conf.all.arp_ignore=1 sysctl -w net.ipv4.conf.all.arp_announce=2
或者将arp参数设置到内核参数配置文件中以让其永久生效。
echo "net.ipv4.conf.all.arp_ignore=1" >>/etc/sysctl.conf echo "net.ipv4.conf.all.arp_announce=2" >>/etc/sysctl.conf sysctl -p
在网上几乎所有文章还设置了lo接口上的arp参数:
echo 1 >/proc/sys/net/ipv4/conf/lo/arp_ignore echo 2 >/proc/sys/net/ipv4/conf/lo/arp_announce
但这没有任何意义,因为从lo接口不受arp参数的影响。
应该在配置VIP之前就设置arp参数,以防止配置VIP后、设置arp抑制之前被外界主机发现。
LVS的调度算法,详细内容见官方手册:http://www.linuxvirtualserver.org/zh/lvs4.html 。
IPVS在内核中的负载均衡调度是以连接为粒度的。在HTTP协议(非持久)中,每次从WEB服务器上获取资源都需要建立一个TCP连接,同一用户的不同请求会被调度到不同的服务器上,所以这种细粒度的调度在一定程度上可以避免单个用户访问的突发性引起服务器间的负载不平衡。
LVS分为两种调度方式:静态调度和动态反馈调度。
静态调度方式是指不管RS的繁忙程度,根据调度算法计算后轮到谁就调度谁。例如两台realserver,一开始双方都在处理500个连接,下一个请求到来前,server1只断开了10个,而server2断开了490个,但是此时轮到了server1,就会调度server1而不管繁忙的程度。
动态调度方式是指根据RS的繁忙程度反馈,计算出下一个连接应该调度谁(动态反馈负载均衡算法考虑服务器的实时负载和响应情况,不断调整服务器间处理请求的比例,来避免有些服务器超载时依然收到大量请求,从而提高整个系统的吞吐率)。
在内核中的连接调度算法上,IPVS已实现了以下八种调度算法:默认的算法为wlc。
前言:在涉及到对外项目,经手许多小中型网站的架构,F5、LVS及Nginx都比较多,我想一种比较通俗易懂的语气跟大家说明下何谓负载均衡,何谓Linux集群,帮助大家走出这个误区,真正意义上来理解它们。