负载均衡_系统设计笔记5

零.从横向扩展说起

从单机扩展到多机,面临的第一个问题就是这些机器如何协同工作,即 如何调度请求

load balancer dispatcher

P.S.关于横向扩展与纵向扩展的详细信息,见 Scalability_系统设计笔记 1

一.负载均衡器

多服务器下的请求调度机制称为负载均衡(Load balancing),调度器(Dispatcher)即负载均衡器(Load balancer):

其主要作用是 根据既定策略(如随机、轮流)将客户端请求分发给各个服务器

The fundamental feature of a load balancer is to be able to distribute incoming requests over a number of backend servers in the cluster according to a scheduling algorithm.

有助于:

  • 防止请求到达不可用的服务器

  • 防止资源过载

  • 消除单点故障,提升可用性

此外,还可以用于:

  • SSL termination:处理 SSL 连接,将加密解密的工作前置到调度层

  • 会话保留(Session persistence):集中处理会话,避免切换服务器造成会话状态丢失

也就是说,多机场景下,必须要有一个负责分发/调度请求的负载均衡器,那么,接下来的问题是 应该在哪一层实现负载均衡机制

二.实现思路

考虑一个 HTTP 请求从客户端到服务器的通信过程,可以简单划分为 3 个阶段:

  • 出发:客户端发出请求

  • 途中:请求经网络传输

  • 到达:服务器收到请求

对请求进行分发/调度,就是要想办法(按既定策略)改变请求的目的地 ,那么,至少有 3 种思路:

  • 出发前:在请求经网络传输之前,就确定最终目的地,例如 DNS 负载均衡、客户端负载均衡

  • 传输中:在网络传输的某些环节改变目的地,例如 4 层负载均衡

  • 到达后:在请求抵达服务器后,进行二次分发,例如 7 层负载均衡

三.DNS 负载均衡

客户端要向服务器发起请求,首先要知道服务器的 IP 地址,通过DNS来查询:

DNS 维护着域名与 IP 地址之间的映射关系,因此可以在这里实现负载均衡策略,将请求指向目标服务器(的 IP 地址),例如:

  • 轮流分发:添加一系列 A 记录,将同一域名指向多个不同的 IP 地址即可,称为 round-robin DNS

  • 随机分发:采用支持多值应答路由策略的 DNS 服务

简单易用,但缺陷也很明显

  • 可靠性没有保障:DNS 并不检查服务器的可用性,即便目标服务器 down 掉了或者无法访问了,也返回其 IP 地址

  • 更新不及时:DNS 的解析结果往往会被层层缓存,记录更新无法立即生效

P.S.关于 DNS 负载均衡的更多信息,见 What Is DNS Load Balancing?

四.客户端负载均衡

同理,把服务器 IP 地址选择机制拿到客户端来实现,就叫客户端负载均衡

由客户端自行选择目标服务器的 IP 地址(不再通过 DNS 查询):

client-side load balancing

例如,向客户端提供服务器 IP 列表,客户端发起请求之前随机选取一个 IP,就能达到随机分发的目的

比起 DNS 负载均衡, 客户端不存在缓存的问题,而且能够进行更精细的控制 ,比如检查服务可用性,并从中选取可用的 IP 地址

五.OSI 七层模型

请求从客户端发出之后,接着通过网络进行传输

OSI(Open System Interconnect)参考模型 将网络通信分为 7 个抽象层:

自下而上,依次为:

  • 物理层(第 1 层):通过物理介质传输原始比特流,即物理信号(Symbol)

  • 数据链路层(第 2 层):提供可靠的节点间数据帧(Frame)传输机制,具体工作包括 MAC 寻址

  • 网络层(第 3 层):决定数据包(Packet)传输将采取的物理路径,支持 IP、ARP 等协议,具体工作包括 IP 寻址、路由和流量控制

  • 传输层(第 4 层):提供可靠的报文(Datagram)传输机制,支持 TCP、UDP 等传输协议,具体工作包括

  • 会话层(第 5 层):负责管理会话,以支持通过多次传输连续交换信息

  • 表现层(第 6 层):将来自网络服务的数据翻译成应用层可用的格式,具体工作包括字符编码转换、数据压缩、加密解密等

  • 应用层(第 7 层):提供高级 API 的人机交互层,应用能够通过该层访问网络服务,如资源共享、远程文件访问等

其中,第 1 层是原始数据,第 2 层确定目标机器的 MAC 地址,第 3 层确定终点的 IP 地址,以及途经的具体路线,到第 4 层,要根据传输协议确定目标端口号,第 5~7 层不关心终点,因为 IP 地址 + MAC 地址 + 端口号已经唯一确定了目标应用程序

也就是说,一个 HTTP 请求必须经由这些层才能到达目标服务器,那么, 理论上,在第 2~7 层中的任意一层都有机会变更终点,实现负载均衡

而常见的负载均衡机制多实现在第 4 层和第 7 层,这是为什么呢?

六.2 层、3 层负载均衡

  • 2 层负载均衡:根据源/目标 MAC 地址进行分发,例如将虚拟 MAC 地址根据既定策略映射到实际 MAC 地址

  • 3 层负载均衡:根据源/目标 IP 地址,以及第 2 层信息进行分发,例如解析虚拟 IP(Virtual IP address)

越靠近底层,所能用来进行分发决策的信息越少 ,所以 2 层负载均衡的实际用途有限,常见的只有冗余网关协议(如 GLBPVRRP )和链路聚合(Link aggregation,也叫 etherchannel)等,具体见 How is load balancing achieved with layer 2 devices?

七.4 层负载均衡

4 层负载均衡基于传输层(第 4 层)信息进行请求分发,包括源/目标 IP 地址,以及数据包头部的端口号, 但不考虑数据包内容

Layer 4 load balancing uses information defined at the networking transport layer (Layer 4) as the basis for deciding how to distribute client requests across a group of servers. For Internet traffic specifically, a Layer 4 load balancer bases the load-balancing decision on the source and destination IP addresses and ports recorded in the packet header, without considering the contents of the packet.

客户端将将负载均衡器的 IP 地址作为目标 IP 地址发起请求,4 层负载均衡器收到请求后,对数据包进行 NAT 转换,将目标 IP 地址修改成实际服务器的地址,在将服务器响应转发给客户端之前,负载均衡器再将源 IP 地址改成自身的 IP 地址。类似的,对数据包中的源/目标端口号也以这种方式进行修改

P.S.第 4 层负载均衡器通常是专用的硬件设备,NAT 操作可能会由专用芯片来完成

与更复杂的 7 层负载均衡相比,4 层负载均衡所需的计算更少,但在目前的硬件条件下,由此带来的性能优势已经不重要了

P.S. 严格来讲,4 层负载均衡应该叫 3/4 层负载均衡 ,因为结合了第 3 层的 IP 地址和第 4 层的端口号信息

八.7 层负载均衡

7 层负载均衡 根据应用层协议信息(如 HTTP 头)以及数据包内容信息进行分发 ,包括 URL、数据类型、Cookie 信息等:

Layer 7 load balancers base their routing decisions on various characteristics of the HTTP header and on the actual contents of the message, such as the URL, the type of data (text, video, graphics), or information in a cookie.

比起 4 层负载均衡,7 层负载均衡可以读取请求和响应内容,所需的计算虽然更多,但不见得比 4 层负载均衡性能更差,因为 拥有更全面的上下文信息,可以在此基础上进行更聪明的全局决策 (比如剔除慢速连接、重定向超时请求),甚至还能对内容进行优化(比如压缩),从而提高性能

P.S. 严格来讲,7 层负载均衡应该叫 5~7 层负载均衡 ,因为结合了 OSI 模型中 5~7 层的相关信息:

TCP/IP model and OSI model

参考资料