纸上得来终觉浅,绝知此事要躬行。
之前我们讲述了可伸缩网络服务的几种结构,它们都需要一个前端调度器。在调度器的实现技术中,IP 负载均衡技术是效率最高的。下面将描述三种 IP 负载均衡技术VS/NAT
、VS/DR
和VS/TUN
的工作原理,以及它们的优缺点。
- VS/NAT
- 通过网络地址转换实现虚拟服务器的方法,将一组服务器构成一个高性能的、高可用的虚拟服务器
- 大多数商品化的 IP 负载均衡调度器产品都是使用此方法,如
Cisco
的LocalDirector
、F5
的Big/IP
- VS/DR:
- 通过直接路由实现虚拟服务器的方法,将一组服务器构成一个高性能的、高可用的虚拟服务器
- VS/TUN:
- 通过IP 隧道实现虚拟服务器的方法,将一组服务器构成一个高性能的、高可用的虚拟服务器
1. 实现框架
系统实现的若干问题可以查看官方文档的说明。
在Linux
内核2.0
和内核2.2
的版本中,通过修改了TCP/IP
协议栈,在IP
层截取和改写/转发IP
报文,实现了三种IP 负载均衡技术,并提供了一个ipvsadm程序进行虚拟服务器的配置和管理。而在Linux
内核2.4
和2.6
中,把它实现为NetFilter
的一个模块,很多代码作了改写和进一步优化,已经较稳定。
系统的主要功能模块如上图所示,“VS Schedule & Control Module”是虚拟服务器的主控模块,它挂接在IP
报文遍历的LOCAL_IN
链和IP_FORWARD
链两处,用于截取/改写 IP 报文;“VS Rules Table”
用于存放虚拟服务器的规则,“Connections Hash Table”
表是用于记录当前连接的Hash表
;“Stale Connection Collector”
模块用于回收已经过时的连接;“Statistics Data”
表记录IPVS
的统计信息。用户空间的ipvsadm
管理程序通过setsockopt()
函数将虚拟服务器的规则写入“VS Rules Table”
表中,通过/proc
文件系统把“VS Rules Table”
表中的规则读出。
当一个IP
报文到达时,若报文的目标地址是本地的IP
地址,IP
报文会转到LOCAL_IN
链上,否则转到IP_FORWARD
链上。IPVS
模块主要挂接在LOCAL_IN
链和IP_FORWARD
链两处。当一个目标地址为Virtual IP Address
的报文到达时,该报文会被挂接在LOCAL_IN
链上的IPVS
程序捕获,若该报文属于在连接Hash
表中一个已建立的连接,则根据连接的信息将该报文发送到目标服务器,否则该报文为SYN
时,根据连接调度算法从一组真实服务器中选出一台服务器,根据 IP 负载调度设置的规则将报文发送给选出的服务器,并在连接 Hash 表中记录这个连接。挂接在IP_FORWARD
链上的IPVS
程序是改写VS/NAT
中服务器响应报文的地址。
连接的Hash 表可以容纳几百万个并发连接,在Linux
内核2.2
和内核2.4
的IP
虚拟服务器版本中每个连接只占用128Bytes
有效内存,例如一个有256M
可用内存的调度器就可调度两百万个并发连接。连接Hash
表的桶个数可以由用户根据实际应用来设定,来降低Hash
的冲突率。
在每个连接的结构中有连接的报文发送方式、状态和超时等。报文发送方式有VS/NAT
、VS/TUN
、VS/DR
和本地结点,报文会被以连接中设定的方式发送到目标服务器。这意味着在一个服务器集群中,我们可以用不同的方式来调度不同的服务器。连接的状态和超时用于记录连接当前所在的状态,如SYN_REC
、ESTABLISHED
和FIN_WAIT
等,不同的状态有不同的超时值。
IP 虚拟服务器具有以下特点:
- 三种 IP 负载均衡技术,在一个服务器集群中,不同的服务器可以使用不同的
IP
负载均衡技术。 - 可装卸连接调度模块,共有五种连接调度算法。
- 高效的
Hash
函数 - 高效的垃圾回收机制
- 虚拟服务的数目没有限制,每个虚拟服务有自己的服务器集。
- 支持持久的虚拟服务
- 正确的
ICMP
处理 - 拥有本地结点功能
- 提供系统使用的统计数据
- 针对大规模
DoS
攻击的三种防卫策略
通过IP
虚拟服务器软件和集群管理工具可以将一组服务器组成一个高性能、高可用的网络服务。该系统具有良好的伸缩性,支持几百万个并发连接。无需对客户机和服务器作任何修改,可适用任何Internet
站点。该系统已经在很多大型的站点得到很好的应用。
2. VS/NAT
由于IPv4
中IP
地址空间的日益紧张和安全方面的原因,很多网络使用保留IP
地址专门为内部网络使用,如10.0.0.0/255.0.0.0
、172.16.0.0/255.128.0.0
和192.168.0.0/255.255.0.0
。当内部网络中的主机要访问Internet
或被Internet
访问时,就需要采用网络地址转换(NAT
),将内部地址转化为Internets
上可用的外部地址。NAT
的工作原理是报文头(目标地址、源地址和端口等)被正确改写后,客户相信它们连接一个IP
地址,而不同IP
地址的服务器组也认为它们是与客户直接相连的。由此,可以用NAT
方法将不同IP
地址的并行网络服务变成在一个IP
地址上的一个虚拟服务。
VS/NAT
的体系结构如下图所示。在一组服务器前有一个调度器,它们是通过Switch/HUB
相连接的。这些服务器提供相同的网络服务、相同的内容,即不管请求被发送到哪一台服务器,执行结果是一样的。服务的内容可以复制到每台服务器的本地硬盘上,可以通过网络文件系统(如NFS
文件系统)共享,也可以通过一个分布式文件系统来提供。
客户通过虚拟服务的 IP 地址(Virtual IP Address
)访问网络服务时,请求报文到达调度器,调度器根据连接调度算法从一组真实服务器中选出一台服务器,将报文的目标地址Virtual IP Address
改写成选定服务器的地址,报文的目标端口改写成选定服务器的相应端口,最后将修改后的报文发送给选出的服务器。同时,调度器在连接**Hash
表**中记录这个连接,当这个连接的下一个报文到达时,从连接Hash
表中可以得到原选定服务器的地址和端口,进行同样的改写操作,并将报文传给原选定的服务器。当来自真实服务器的响应报文经过调度器时,调度器将报文的源地址和源端口改为Virtual IP Address
和相应的端口,再把报文发给用户。我们在连接上引入一个状态机,不同的报文会使得连接处于不同的状态,不同的状态有不同的超时值。在TCP
连接中,根据标准的TCP
有限状态机进行状态迁移;在UDP
中,我们只设置一个UDP
状态。不同状态的超时值是可以设置的,在缺省情况下,SYN
状态的超时为1
分钟,ESTABLISHED
状态的超时为15
分钟,FIN
状态的超时为1
分钟;UDP
状态的超时为5
分钟。当连接终止或超时,调度器将这个连接从连接Hash
表中删除。
这样,客户所看到的只是在Virtual IP Address
上提供的服务,而服务器集群的结构对用户是透明的。对改写后的报文,应用增量调整Checksum
的算法调整TCP Checksum
的值,避免了扫描整个报文来计算Checksum
的开销。
在一些网络服务中,它们将 IP 地址或者端口号在报文的数据中传送,若我们只对报文头的 IP 地址和端口号作转换,这样就会出现不一致性,服务会中断。所以,针对这些服务,需要编写相应的应用模块来转换报文数据中的 IP 地址或者端口号。我们所知道有这个问题的网络服务有FTP
、IRC
、RSTP
、PPTP
等。
下面,举个例子来进一步说明VS/NAT
,如下图所示:
VS/NAT
的配置如下表所示,所有到IP
地址为202.103.106.5
和端口为80
的流量都被负载均衡地调度的真实服务器172.16.0.2:80
和172.16.0.3:8000
上。目标地址为202.103.106.5:21
的报文被转移到172.16.0.3:21
上。而到其他端口的报文将被拒绝。
从以下的例子中,我们可以更详细地了解报文改写的流程。
访问Web
服务的报文可能有以下的源地址和目标地址:
调度器从调度列表中选出一台服务器,例如是172.16.0.3:8000
。该报文会被改写为如下地址,并将它发送给选出的服务器。
从服务器返回到调度器的响应报文如下:
响应报文的源地址会被改写为虚拟服务的地址,再将报文发送给客户:
这样,客户认为是从202.103.106.5:80
服务得到正确的响应,而不会知道该请求是服务器172.16.0.2
还是服务器172.16.0.3
处理的。
3. VS/TUN
在VS/NAT
的集群系统中,请求和响应的数据报文都需要通过负载调度器,当真实服务器的数目在10
台和20
台之间时,负载调度器将成为整个集群系统的新瓶颈。大多数Internet
服务都有这样的特点:请求报文较短而响应报文往往包含大量的数据。如果能将请求和响应分开处理,即在负载调度器中只负责调度请求而响应直接返回给客户,将极大地提高整个集群系统的吞吐量。
IP 隧道(IP tunneling
)是将一个IP
报文封装在另一个IP
报文的技术,这可以使得目标为一个IP
地址的数据报文能被封装和转发到另一个IP
地址。IP
隧道技术亦称为IP
封装技术。IP
隧道主要用于移动主机和虚拟私有网络,在其中隧道都是静态建立的,隧道一端有一个IP
地址,另一端也有唯一的IP
地址。
我们利用IP
隧道技术将请求报文封装转发给后端服务器,响应报文能从后端服务器直接返回给客户。但在这里,后端服务器有一组而非一个,所以我们不可能静态地建立一一对应的隧道,而是动态地选择一台服务器,将请求报文封装和转发给选出的服务器。这样,我们可以利用IP
隧道的原理将一组服务器上的网络服务组成在一个IP
地址上的虚拟网络服务。VS/TUN
的体系结构如下图所示,各个服务器将VIP
地址配置在自己的IP
隧道设备上。
VS/TUN
的工作流程如下图所示:它的连接调度和管理与VS/NAT
中的一样,只是它的报文转发方法不同。调度器根据各个服务器的负载情况,动态地选择一台服务器,将请求报文封装在另一个IP
报文中,再将封装后的IP
报文转发给选出的服务器;服务器收到报文后,先将报文解封获得原来目标地址为VIP
的报文,服务器发现VIP
地址被配置在本地的IP
隧道设备上,所以就处理这个请求,然后根据路由表将响应报文直接返回给客户。
在这里,请求报文的目标地址为VIP
,响应报文的源地址也为VIP
,所以响应报文不需要作任何修改,可以直接返回给客户,客户认为得到正常的服务,而不会知道是哪一台服务器处理的。
在VS/TUN
中,响应报文根据服务器的路由表直接返回给客户,而不经过负载调度器,所以负载调度器只处于从客户到服务器的半连接中,VS/TUN
的TCP
状态迁移与VS/NAT
的不同。我们给出半连接的TCP
有限状态机,如下图所示,圈表示状态,箭头表示状态间的转换,箭头上的标识表示在当前状态上收到该标识的输入,迁移到下一个状态。VS/TUN
的TCP
状态迁移是按照半连接的TCP
有限状态机进行的。
即在负载调度器中只负责调度请求,而响应由真实服务器直接返回给客户。
4. VS/DR
跟VS/TUN
方法相同,VS/DR
利用大多数Internet
服务的非对称特点,负载调度器中只负责调度请求,而服务器直接将响应返回给客户,可以极大地提高整个集群系统的吞吐量。该方法与IBM
的NetDispatcher
产品中使用的方法类似,但IBM
的NetDispatcher
是非常昂贵的商品化产品。
VS/DR
的体系结构如下图所示:调度器和服务器组都必须在物理上有一个网卡通过不分段的局域网相连,即通过交换机或者高速的HUB
相连,中间没有隔有路由器。VIP
地址为调度器和服务器组共享,调度器配置的VIP
地址是对外可见的,用于接收虚拟服务的请求报文;所有的服务器把VIP
地址配置在各自的Non-ARP
网络设备上,它对外面是不可见的,只是用于处理目标地址为VIP
的网络请求。
VS/DR
的工作流程如下图所示:它的连接调度和管理与VS/NAT
和VS/TUN
中的一样,它的报文转发方法又有不同,将报文直接路由给目标服务器。在VS/DR
中,调度器根据各个服务器的负载情况,动态地选择一台服务器,不修改也不封装IP
报文,而是将数据帧的MAC
地址改为选出服务器的MAC
地址,再将修改后的数据帧在与服务器组的局域网上发送。因为数据帧的MAC
地址是选出的服务器,所以服务器肯定可以收到这个数据帧,从中可以获得该 IP 报文。当服务器发现报文的目标地址VIP
是在本地的网络设备上,服务器处理这个报文,然后根据路由表将响应报文直接返回给客户。
在VS/DR
中,请求报文的目标地址为VIP
,响应报文的源地址也为VIP
,所以响应报文不需要作任何修改,可以直接返回给客户,客户认为得到正常的服务,而不会知道是哪一台服务器处理的。
VS/DR
负载调度器也只处于从客户到服务器的半连接中,按照半连接的 TCP 有限状态机进行状态迁移。
5. 优缺点比较
三种 IP 负载均衡技术的优缺点归纳在下表中:
注:以上三种方法所能支持最大服务器数目的估计是假设调度器使用 100M 网卡,调度器的硬件配置与后端服务器的硬件配置相同,而且是对一般 Web 服务。使用更高的硬件配置(如千兆网卡和更快的处理器)作为调度器,调度器所能调度的服务器数量会相应增加。当应用不同时,服务器的数目也会相应地改变。所以,以上数据估计主要是为三种方法的伸缩性进行量化比较。