负载均衡

来源:互联网 发布:唯品会内部优惠券软件 编辑:程序博客网 时间:2024/04/28 22:21
原文转载:http://blog.chinaunix.net/uid-26548237-id-3363911.html
作者:gfree.wind@gmail.com
博客:blog.focus-linux.net   linuxfocus.blog.chinaunix.net
 
微博:weibo.com/glinuxer
QQ技术群:4367710
 
本文的copyleft归gfree.wind@gmail.com所有,使用GPL发布,可以自由拷贝,转载。但转载请保持文档的完整性,注明原作者及原链接,严禁用于任何商业用途。
======================================================================================================
本系列文章均来源于书籍《Load Balancing Servers, Firewalls, and Caches》,均为书中的知识点,稍稍加上作者从事这行业的一些经验——应该是不涉及公司机密呵。。。

我们公司的核心产品就是负载均衡产品,所以有时候想写些这方面的文章,也不敢下笔呵——怕泄露公司机密呵。不过最近看到一本书《Load Balancing Servers, Firewalls, and Caches》。目前已经翻看了四章,觉得讲得不错。虽然并不涉及内部的具体实现,但是可以帮助读者从无到有的理解负载均衡设备。对我来说,也可以帮助我重新整理一下系统知识。既然这方面的东西已经有书籍讲解了,那么就谈不上什么涉密不涉密了。

第一个问题:什么是负载均衡设备?
简单的看,负载设备作为服务器的前端设备,负责将流量根据各种策略分发到后端各个真正的服务器上,从而使后端的服务器群得到合理有效的应用。从这个定义上看,感觉这个设备功能很简单。按照通用的设计方法,一般都是在第一个包的时候,根据策略选择后端的服务器,建立session,也就是slow path。后面的包通过session表,得到session后,直接利用上次的结果,将包发给相同的服务器,也就是fast path。但是负载均衡设备,还有另外一个名字,叫做4-7层交换机。我们知道,2层交换机是根据MAC table来交换数据,三层交换机是根据IP 信息来交换数据,也就是路由。4层呢,即根据port来交换数据,也是负载均衡设备实现的基础——这个后面的文章具体讲解。7层,则是要根据7层的具体应用层协议的payload来交换数据。(为啥没有5和6层?呵呵,TCP/IP只有5层,下面四层与OSI的分层一样,第5层却又直接使用OSI的层次,即第7层应用层。至于为啥这样?我也不知道呵)。负载均衡设备,作为4-7层交换机,自然需要兼容2层和3层的交换协议,也就是说可以把负载均衡设备当作一个路由器或者交换机使用。负载均衡设备的应用场景,也是要求其必须支持2-3层的交换协议。不过肯定当不了核心网的路由器呵。这样的话,单单的数据交换功能就已经不简单了吧。而为了支持7层交换,其必须支持各种7层协议,且要有辅助的一些功能,如health check,简单的DDOS保护等。

第二个问题:为什么需要负载均衡设备?
负载均衡设备的主要用户就是大型网站,ISP,或者大型企业的内部网络。对于这些用户来说,他们的网络时刻承受着巨大的网络流量,所以需要部署很多服务器。在部署这些服务器的时候,他们需要保证网络的可扩展性,服务器的易管理性和可靠性。在没有前端的负载均衡设备的时候,很难达到这三个目标。而使用了负载均衡设备,实现这三个目标,简直是轻而易举。下面看看负载均衡设备怎么实现的这三个需求。
下图为负载均衡设备的一个常见的部署:


负载均衡设备作为服务器前端设备,拥有公网IP连到互联网上,一般一种服务拥有一个VIP。client发送请求到负载均衡设备,然后负载均衡设备根据策略将请求转发到后端的服务器上。服务器将请求回复到负载均衡设备,再将其转发给client。这种服务器部署,对于client来说,完全是透明的。它不知道有多少个后端服务器,提供服务的又是哪台服务器。对客户端来说,看到的只是负载均衡设备,提供服务的也是负载均衡设备。

可扩展性的支持:客户可以添加更多的后端服务器,只需要将其加入到负载均衡设备的该服务组中即可。
易管理性:添加/删除服务器,只需要更改负载均衡设备的配置,不会对用户造成任何的影响。
可靠性:当提供服务的某台服务器发生故障时,不需要进行任何配置改动,负载均衡设备可以主动探测到故障服务器。可将后来的请求转发到其它服务器,不影响用户的正常使用。
作者:gfree.wind@gmail.com
博客:blog.focus-linux.net   linuxfocus.blog.chinaunix.net
 
微博:weibo.com/glinuxer
QQ技术群:4367710
 
本文的copyleft归gfree.wind@gmail.com所有,使用GPL发布,可以自由拷贝,转载。但转载请保持文档的完整性,注明原作者及原链接,严禁用于任何商业用途。
======================================================================================================
本系列文章均来源于书籍《Load Balancing Servers, Firewalls, and Caches》,均为书中的知识点,稍稍加上作者从事这行业的一些经验——应该是不涉及公司机密呵。。。

今天的主题是Load Balance设备与Server Farm服务器群。


上图为Load Balance与Server Farm的一个简单的网络拓扑图。
Load Balance上面需要配置一个Virtual Server,拥有一个Virtual IP。在TCP/IP协议中,port是用于区分服务的,所以virtual server下面同样要配置virtual port,对应不同的服务,并绑定多个real server的对应port。

对于client来说,只有virtual ip是可见的,后面的real server全部不可见。client发送请求到ld上,由ld负责挑选一个合适的real server来提供真正的服务。使用SLB可以提供以下几个好处:
1. 可扩展性:由于提供的服务的server可以有很多个,所以ld的性能要好于一个超级server。假设后面有N个real server,每个server提供服务的性能为P,那么总性能的理论上限就是NP。但是由于选择算法不可能完美,再加上ld毕竟需要处理包而带来的性能损耗,所以使用slb后的总性能可以达到(0.8~0.9)*NP。
2. 可靠性:LB会对real server进行health check。当发现某个real server不能提供服务后,后续的请求均不会发给这个server。而一旦该server恢复后,LB也会恢复对该server的使用。这一过程完全对用户透明。
3. 可管理型:有了LB,可以对某台server随时进行升级、维修和检测,而不会影响任何用户的使用。还可以对服务质量,服务内容进行管理。由专门的服务器提供特定的服务和内容。通过LB来选择正确的对应的服务器。
4. 安全性:首先LB作为服务器的前端设备,本身就具备一定的安全防护能力——这也是必须的呵。如对DDOS的防御等。但我认为,对server最有力的保护是这个网络拓扑。在这个拓扑中,real server本身可以完全没有公网IP,只有LB才能访问real server。外界根本无法访问server,又怎么能够进行攻击呢。

下面是一个简单的数据包流程(LB充当real server的网关设备):
1. client发送请求到virtual server;
2. lb查看数据包的目的IP是否匹配某个VIP;
3. 确定VIP后,lb查看数据包的目的port是否匹配某个virtual port;
4. 根据选择算法和策略,选定real server,将数据包转发给real server。这里不可避免的要对数据包的2、3层头部进行更改;并根据需要,确定是否建立一个session。
5. 收到server的回复后,根据session或者包本身的内容,将其转发给client。

这是一个简单的数据包流程。我们考虑一下这样的流程的缺点:
1. 虽然client只能看到VIP,但是real server看到的却是真实的client IP。这样虽然不会有直接的问题,但是这意味着,LB与real server之间的连接要依赖于client端的IP。也就是说,client与LB之间的连接,和LB与real server之间的连接,是紧密耦合的。这样的话,LB与real server之间的连接只能为唯一的一个client服务。
2. 根据上面的数据包流程,对于TCP来说,在三次握手的阶段就要选择server。对于七层应用来说,这样的选择是不合理的。
为了避免上面的缺点,我们需要将client-LB和LB-server这两个连接分开。这时,我就要引入Source NAT——前面的流程中,将数据包的目的地址VIP改为real IP,这个我们可以称之为Destination NAT。Source NAT是在LB转发数据包给real server的时候,使用LB拥有的source nat IP来替换数据包中的源目的地址。收到server的response时,做相反的工作。通过source NAT,server段看到的地址都是属于LB的。这样就与某个固定的client分离开来,该连接就变成了LB与server之间自己独立的连接,解除了与client的耦合。这样,一方面LB-server的连接可以服务多个client,另一方面选择server的时机可以延迟到完成了client-server连接的三次握手,并获得了完整的七层信息时。这时,可以通过七层的信息来选择合适的server了。当然,SNAT与DNAT在LB中还有更多的应用场景,这里就不一一叙说了。以后有合适的机会,再详细的分享。


对于SLB来说,health check是一个重要的功能。LB需要及时确定后端服务器是否可用,才能提供可靠的服务。health check分为两种,一种为in-band ,另外一种自然是out-band。in-band,顾名思义,是利用正常的数据流来确定server是否可用。比如TCP无法连接real server超时等。而out-band,则是由LB自发的去检测real server。这时可以支持各种不同的方法去检测后端server。比如是否ping通,是否可以连通,是否可以获取指定内容等,甚至可以支持用户自定义的脚本或行为来决定server是否正常。