关于负载均衡那点事儿的一些浅见

发布时间:2020-04-20 16:48:19 作者:三月
来源:亿速云 阅读:303

下文给大家带来关于负载均衡那点事儿的一些浅见,希望能够给大家在实际运用中带来一定的帮助,负载均衡涉及的东西比较多,理论也不多,网上有很多书籍,今天我们就用亿速云在行业内累计的经验做一个解答。

 网络负载均衡和代理是什么?

Wikipedia 对负载均衡的定义 是:

In computing, load balancing improves the distribution of workloads across multiple computing resources, such as computers, a computer cluster, network links, central processing units, or disk drives. Load balancing aims to optimize resource use, maximize throughput, minimize response time, and avoid overload of any single resource. Using multiple components with load balancing instead of a single component may increase reliability and availability through redundancy. Load balancing usually involves dedicated software or hardware, such as a multilayer switch or a Domain Name System server process.

关于负载均衡那点事儿的一些浅见

中文版:

负载平衡(Load balancing)是一种计算机网络技术,用来在多个计算机(计算机集群)、网络连接、CPU、磁盘驱动器或其他资源中分配负载,以达到最优化资源使用、最大化吞吐率、最小化响应时间、同时避免过载的目的。使用带有负载平衡的多个云服务器组件,取代单一的组件,可以通过冗余提高可靠性。负载平衡服务通常是由专用软件和硬件来完成。

上面的定义不仅包含了网络,还包含了计算的所有方面。操作系统、网络以及容器编排器等都有各自的负载均衡技术,用于使用各自的资源进行各自的任务调度。本文仅就网络负载均衡进行探讨。

1:网络负载均衡概览

 对网络负载均衡进行了一个高层次的概括。多个客户端向多个后端发起资源请求,负载均衡器处于客户端和后端之间,简单来说完成如下任务:

在分布式系统中合理的使用负载均衡能带来很多好处:

负载均衡器 vs 代理服务器

业内谈到网络负载均衡器,Load Balancer 以及 Proxy 这两个术语经常会同样对待,本文中也把这两个词条等价处理(卖弄一下:并非所有的代理都是负载均衡器,但是负载均衡是主流代理的首要功能)。

有人可能会问,有的负载均衡功能是作为客户端库的内置功能完成的,这种负载均衡器就不是代理服务器。这一话题本就容易混淆,这一质问更加让人糊涂。文中会详述这种负载均衡器的拓扑,这种嵌入的负载均衡方式只是代理的一种特例,应用通过内嵌的库来完成代理职能,跟典型的负载均衡器的区别仅在于进程内外而已,其整体抽象是一致的。

四层(连接/会话)负载均衡

业界在讨论负载均衡技术的时候,经常会分为两类:L4 和 L7。这一分类来源于 OSI 模型的四层和七层的定义。OSI 模型无法很好的描述负载均衡方案中的复杂性,一个四层负载均衡在完成传统的四层协议任务例如 UDP 和 TCP 之外,往往还会加入了其他层次的内容。例如一个四层的 TCP 负载均衡还支持 TLS 功能,这算七层负载均衡了么?

2:TCP 终端四层负载均衡

图 2 展示了一个传统的四层 TCP 负载均衡器。这个例子中,客户端向负载均衡器发起了一个 TCP 连接,负载均衡器 终结 了这一连接(也就是说直接响应了 SYN),接下来选择一个后端,然后创建了到后端的新的 TCP 连接(就是发起了新的 SYN)。图中的细节不需太过关注,后面的四层负载均衡章节会进行详细讨论。

本节的关键点是四层负载均衡一般只在四层的 TCP/UDP 进行操作。笼统的说,负载均衡器负责操作这些字节,保证同一会话的字节们只跟同一个后端打交道。四层负载均衡对通信中的应用细节是一无所知的。通信内容可以是 HTTP、RedisMongoDB 或者任何应用协议。

七层(应用)负载均衡

四层负载均衡很简单,目前还在大面积使用。四层负载均衡有什么短处,以至于需要七层(应用)负载均衡呢?例如下面几个四层的案例:

在上述场景中,为客户端 A 服务的后端,其负载水平仅相当于为客户端 B 服务的后端的约 1/3000 左右,这明显违背了负载均衡器的初衷。在所有多工、保持连接的协议中都会发生这样的情况(多工意思是在单一四层连接中并行发送应用请求;保持连接则意味着在没有活动请求的情况下,也不会关闭连接)。出于性能方面的考虑(创建连接的成本通常较高,尤其是当使用 TLS 对连接进行加密的情况下),所有的现代协议都包含这两个特性,所以随着时间的推移,四层负载均衡的负载不均的情况会越发明显。七层负载均衡能够解决这一问题。

图三:HTTP/2 七层终端负载均衡


图 3 描述了七层的 HTTP/2 负载均衡。这里客户端发起了对负载均衡的单个连接。负载均衡器连接到了两个后端。当客户端向负载均衡器发送两个 HTTP/2 流的时候,两个流会分别送往不同后端。这样多工客户端的大量不同的请求会被高效的分发给多个后端。这就是七层负载均衡对现代协议的重要性的来由(因为对应用流量的洞察能力,七层负载均衡还有很多其他好处,后面会详细描述)。

七层负载均衡和 OSI 模型

之前四层负载均衡章节中说过,用 OSI 模型来描述负载均衡是有困难的。OSI 描述的第七层,涵盖了负载均衡的多方面功能的臭显。比如对 HTTP 来说,有以下几个低级一些的层次:


一个成熟的的七层负载均衡器应该照顾到上面描述的每一层次。另一个七层负载均衡器可能只支持七层分类中的特性的一个子集。总而言之,七层负载均衡器的范畴包含了远超四层的为数众多的功能(例子中只提到了了 HTTP;Redis、Kafka、MongoDB 等也都是七层应用协议的例子,也都应受益于七层负载均衡)。

2


负载均衡器特性

下面简单汇总一下负载均衡器的高层功能。并非所有负载均衡器都提供了所有功能。

服务发现

服务发现就是负载均衡器用于决定可用后台列表的过程。这一功能的实现方式花样百出,下面举一些例子:

健康检查

负载均衡器使用健康检查功能,来检测后端是否可用。健康检查有两种实现思路:

负载均衡

是的,负载均衡器必须为负载做均衡。有了一系列的健康后端,如何选择后端来响应一个请求或者连接呢?负载均衡算法是一个活跃的研究领域,有 Round Robin 这样的简单办法,也有通过延迟和后端负载情况进行判断的复杂方案。 Power of 2 least request load balancing 一文,介绍了最流行的兼顾性能和简易的负载均衡算法之一。

随机选择两个后端,进一步选择其中负载较低的一个。

Session 粘连

在某些应用中有一个重要需求:同一会话的请求需要到达同一后端。对于缓存、临时复杂状态等场景来说这是很必要的。对于“同一会话”的定义有多种形式,可能包括 HTTP Cookie、客户端连接的属性以及其他属性。很多七层负载均衡器具有一些对会话粘连的支持。然而我认为会话粘连是一种天然易碎的情况(处理会话的后端可能会瘫痪),所以对于依赖会话的系统设计应该多加小心。

TLS 终端

TLS 这一话题,不管是边缘服务还是服务间通讯,都值得大书特书。因此很多七层负载均衡器在 TLS 处理方面都做了大量工作,其中包含终端、证书校验和绑定,使用 SNI 提供证书等功能。

观测性

我常说:“观测性、观测性、观测性。”,网络是一个天生不可靠的东西,负载均衡器应该提供状态、跟踪以及日志,协助运维人员甄别故障,从而进行修复。负载均衡器的检测输出差距很大。高级的负载均衡器供应包含数字统计、分布式跟中和自定义日志的大量输出。我认为增强的观测性并不是从天而降的,负载均衡器需要做出很多附加工作来完成这一任务。对性能造成的负面影响,相对于这一系列数据的好处来说,不值一提。

安全性和拒绝服务***防范

在边缘部署拓扑(后面会讲解)中,负载均衡器经常需要实现各种包含频率限制、认证以及 DoS 防范(例如 IP 地址的标记和辨识、Tarpitting等方式)等在内的安全功能。

配置和控制平面

负载均衡器应该是可配置的。在大规模部署中,这是一个重要的工作量。通常来说,用来配置负载均衡器的系统被称为“控制平面”,会有多种实现。拙作 Service Mesh Data Plan vs Control Plan 中对这一部分内容作了更深入的探讨。

还有很多

这部分只是对于负载均衡器的功能层面作了一些介绍。下面还会在七层负载均衡器方面做更多的深入讨论。

3


负载均衡器的拓扑分类

我们已经对负载均衡器的概念作了一些概括的介绍,四层和七层负载均衡器的区别,以及负载均衡器特性的汇总,接下来我们会针对分布式系统中的负载均衡器部署拓扑进行一些探讨(下面的每一种拓扑都是适用于四层和七层负载均衡器的)。

中间代理


4:中间代理负载均衡拓扑


图 4 描述的这种拓扑对多数读者来说都是最熟悉的。这一类别包括了 Cisco、Juniper、F5 等硬件产品;云软件解决方案例如 Amazone 的 ALB 和 NLB 以及 Google 的 Cloud Load Balancer,还有 HAProxy、NGINX 以及 Envoy 这样的纯软件自主方案。中间代理方案的优势在于对用户提供的简便性。

一般情况下用户只要通过 DNS 连接到负载均衡器即可,无需担心其他情况;弱势在于,负载均衡器存在单点失败的风险,同时也是可能的性能瓶颈。中间代理通常是一个不便运维的黑盒子。问题出现在哪里?是客户端还是物理网络?是中间代理还是后端?很难界定。

边缘代理

5:边缘代理负载均衡拓扑


图 5 实际上是中间代理的一种变体,这种负载均衡器可以通过 Internet 进行访问。在这一场景下,负载均衡器通常需要提供一些附加的 “API 网关”类功能,例如 TLS 终端、频率限制、认证以及流量路由等。优势和劣势跟中间服代理类似。在一个大的面向 Internet 的分布式系统中,边缘服务器通常是一个必要的组成部分。

客户端通常会使用某个不受服务提供商控制的网络库,通过 DNS 来访问这一系统(后面将会讨论的嵌入客户库或者 Sidecar 代理拓扑都不适合直接运行在客户端)。另外为了安全方面的考虑,为所有的面向 Internet 的流量使用单一的网关来提供入站流量是一个普遍要求。

嵌入式客户库

6:通过嵌入客户端库实现负载均衡


为了克服随中间代理而出现的单点失败以及性能问题,很多成熟架构把负载均衡直接植入如图 6 所示的客户端库中。不同的库所支持的功能差别很大,此类产品中最知名的功能丰富的包括 Finagle、Eureka/Ribbon/Hystrix 以及 gRPC(大致基于 Google 的一个称为 Stubby 的内部系统)。这种方式的好处是把所有负载均衡特性完全分布到每个客户端,从而避免了前面说到的单点失败和性能瓶颈。

这种做法的弱势也很明显,一个组织使用的所有语言,都需要实现这种客户端库。分布式架构下,这种多语言支持的要求会越来越多。这种环境里,每种语言的网络库实现造成的成本会让人望而却步。最后,在大的服务架构中进行库升级也是一个很大的挑战,而在生产环境中并行运行不同的版本,又会给运维造成更大压力。

结合上面的优劣势分析,可以知道,在能够限制编程语言使用,并克服升级痛苦的情况下,这种架构是可以获得成功的。

Sidecar 代理

 7:Sidecar 代理实现负载均衡


嵌入式客户库的一个变体就是图 7 中的 Sidecar 代理拓扑。近年来,这一拓扑以 “Service Mesh” 的概念日益流行。Sidecar 代理背后的思路是,以进程间通信造成的些许延迟为代价,在无需顾虑编程语言锁定的情况下获得嵌入客户端库的各种优点。目前流行的 Sidecar 负载均衡包括 Envoy、NGINX、HAProxy 以及 Linkerd,我的两篇文章:Introducing Envoy 和 Service Mesh Data Plan vs Control Plan 对这种结构进行了更细致的描写。

不同负载均衡器拓扑的总结和优劣势


总的来说,我认为在服务对服务的情况下,Sidecar 代理拓扑(Service Mesh)会逐渐代替所有其他拓扑形式。为了处理进入 Service Mesh 之前的流量,边缘代理拓扑会长期存在。


4


四层负载均衡的现状

四层负载均衡器还有用么?

本文已经谈论了很多七层负载均衡器对现代协议的好处,后面还会谈到七层负载均衡的功能细节。这是否意味着四层负载均衡器无需存在了?不是的。虽然我认为最终七层负载均衡会完全在服务对服务的场景中取代四层负载均衡器,但四层负载均衡器对边缘通信还是非常有意义的,这是因为所有现代的大型分布式架构都是用了两层的四层/七层负载均衡架构来处理互联网流量。在七层负载均衡器之前部署独立的四层负载均衡器的好处是:

下文中我会讲到集中不同设计的中间/边缘四层负载均衡器。后面提到的设计通常是无法用在客户库或 Sidecar 拓扑中的。

TCP/UDP 终端负载均衡器

 8:四层终端负载均衡器


还在应用的第一种四层负载均衡器是图 8中的终端负载均衡器。这和我们介绍四层负载均衡的时候讲到的内容是一致的。这种类型的负载均衡器中,使用了两个的独立的 TCP 连接:一个用于客户端和负载均衡器之间;另一个用在负载均衡器和后端之间。

四层终端负载均衡器还有两个原因:

  1. 实现相对简单。

  2. 靠近客户端的连接终端对性能有显著影响。尤其是如果客户使用有损网络(例如蜂窝网)的话,在进入稳定的有线传输到最终目的之前,是容易发生重传的。换句话说,这种负载均衡器适用于在存在点(Point of Presence )场景下的原始 TCP 连接。


TCP/UDP 透传负载均衡器


9:透传负载均衡器


四层负载均衡器的另一种类型就是图 9所说的透传负载均衡器。这种类型的负载均衡过程中,TCP连接没有被负载均衡器终结,每个链接的数据包,在经过连接分析和网络地址转换(NAT)过程之后,都被转发给一个选中的后端。首先让我们定义一下连接跟踪和 NAT:


有了连接跟踪和 NAT,负载均衡器就能把客户端的 TCP 流量几乎原封不动的的转发给后端。例如客户端同1.2.3.4:80进行通信,选中的后端是10.0.0.2:9000。客户端的 TCP 数据包会到达位于1.2.3.4:80的负载均衡器。负载均衡器会把目标 IP 和端口替换为10.0.0.2:9000;同时还会把源 IP 替换为负载均衡器的 IP。当后端响应 TCP 连接时,数据包就会返回给负载均衡器,负载均衡器中的链接跟踪和 NAT 再次发挥作用,反向送回数据包。

为什么会使用这一种负载均衡器,而不是前面提到的终端型呢?


Direct Server Return (DSR)

10:四层 DSR

图 10展示的就是 DSR 负载均衡。DSR 构建在前文提到的透传负载均衡器的基础之上。DSR 是一种优化方案,只有入站/请求数据包通过负载均衡;出站/响应数据包绕过负载均衡器直接返回给客户端。使用 DSR 方案的有趣之处在于,很多负载的响应比请求数据量大很多(比如典型的 HTTP 请求和响应)。假设 10% 的流量是请求,另外 90% 是响应,如果使用了 DSR 负载均衡,仅需要 1/10 的容量就能够满足系统需要。从前的负载均衡非常昂贵,这一方案能够显著降低系统成本并提高可靠性(更少就是更好)。DSR 负载均衡器用下面的方式扩展了透传负载均衡的概念:


注意不管是 DSR 还是透传负载均衡器,其中的连接跟踪、NAT、GRE 等组成部分都有很多不同设计方式。这些设置从负载均衡器到后端都会涉及。这部分内容超出了本文的范围,就不再深入进行了。

使用高可用配对方式实现容错


11:使用 HA 对和连接跟踪实现容错


到现在,我们要考虑四层负载均衡的容错设计了。不管是 DSR 还是透传负载均衡都需要一定数量的链接跟踪和状态数据存储在负载均衡器中。负载均衡器宕机了会怎样?——所有经过这一负载均衡器的连接都会断掉。可能对应用产生显著影响。

历史上,四层负载均衡器是一种从典型供应商(Cisco、Juniper、F5 等)采购的硬件。这些设备非常昂贵,能够处理大量通信。为了防止单点失败导致的所有连接中断,引发应用故障,负载均衡器通常会使用高可用配对的方式进行部署,如图 11 所示。典型的高可用负载均衡器配置会满足如下设计:


上面的设置是目前很多互联网上的高流量应用还在持续使用的方式,但是这种方案有一些副作用:

使用分布式一致性哈希进行容错和伸缩


12:四层负载均衡器和一致哈希实现容错和伸缩


前文介绍了通过高可用配对的方式来进行负载均衡器的容错设置,以及随之而来的问题。千禧年初,一些大的互联网基础设施提供商开始设计和部署新的图 12 模式的并行四层负载均衡系统。这类系统的目标是:


四层负载均衡器的设计是 fault tolerance and scaling via clustering and distributed consistent hashing 的最佳引用,具体工作模式是:


接下来看看这种设计如何克服 HA 配对方式的缺点:


行文至此,有读者可能会问:“为什么不让边缘路由器直接通过 ECMP 和后端进行通信?为什么我们还需要负载均衡器?”。答案是 DoS 防范以及后端运维难度。如果没有负载均衡器支持,每个后端都需要加入 BGP,而且难于进行滚动更新。

所有的现代四层负载均衡系统都在向着这一方案(或其变体)迁移。两个最为公众所知的例子就是 Google 的 Maglev 以及 Amazon 的 Network Load Balancer (NLB)。目前还没有任何开源负载均衡器实现了这一设计,然而据我所知,有公司要在 2018 年发布一个这样的产品。我很期待他的出现,这一产品将会填补开源网络组件的重要空白。

当前七层负载均衡的技术状态


Current state of the art in L7 load balancing The proxy wars in tech currently is quite literally the proxy wars. Or the "war of the proxies". Nginx plus, HAProxy, linkerd, Envoy all quite literally killing it. And proxy-as-a-service/routing-as-a-service SaaS vendors raising the bar as well. Very interesting times!

是的,的确是这样。近几年我们看到七层负载均衡/代理技术的开发工作开始复兴。随着分布式微服务系统的不断推进,这方面也会不断进步。从基础上看,目前对于靠不住的网络的依赖越发严重,带来更高的运维难度。从长远看,自动伸缩、容器编排等技术的大量使用,意味着静态 IP、静态文件的时代已经过去了。系统不仅更多的使用网络,而且更加动态,需要新的负载均衡功能。在本节中我们简单归纳一下现在七层负载均衡器的功能。

协议支持

现代七层负载均衡器加入了很多不同协议的显式支持。负载均衡器对应用通讯认识越多,就越能做好监控输出、高级负载均衡和路由等功能。例如目前 Envoy 显式的支持七层协议解析和路由的范围包括 HTTP/1、HTTP/2、gRPC、Redis、MongoDB 以及 DynamoDB。包括 MySQL 和 Kafka 在内的更多协议会逐渐添加进来。

动态配置

如上文所述,分布式系统的大行其道,需要有动态配置能力来提高系统的动态和控制能力。Istio就是一个这种系统的例子。请参考 Service Mesh Data Plan vs Control Plan 来获取更多这方面的内容。

高级负载均衡

七层负载均衡器一般都有内置的高级负载均衡支持,例如超时、重试、频率控制、断路器、Shadow、缓冲、基于内容的路由等。

可观测性


上文中也提到过,负载均衡的一个常见功能,越来越多的动态系统被部署,调试难度也水涨船高。健壮的协议规范观测输出可能是未来七层负载均衡器要提供的最重要功能之一。统计数字、分布式跟踪以及可以定义日志的输出,目前已经成为对器层负载均衡解决方案的必须要求。

扩展性

现代七层负载均衡器需要能够简单的加入定制功能。这一功能可以通过编写可插接过滤器,并载入到负载均衡器的方式来实现。很多负载均衡器还支持脚本扩展,例如 Lua。

容错

在讲四层负载均衡的容错时颇费了一番口舌。七层负载均衡的容错又怎样呢?一般来说我们认为七层负载均衡器(的工作负载)是无状态的可抛弃的。使用普通软件就能够简单的对七层负载均衡器进行水平扩展。另外七层负载均衡的流量处理和状态跟踪的复杂度要远超四层。设置七层负载均衡器的 HA 配对在技术上是可行的,但会非常繁杂。

总的说来,不管是四层还是七层的负载均衡,业界都在尝试走出 HA 配对模式,转向一致性哈希为基础的水平扩展方式。

更多

七层负载均衡器正在高速发展。可以参考 Envoy 架构概览。

5


全局负载均衡和中心控制平面

13:全局负载均衡

未来会有越来越多的独立负载均衡器以商品设备的面目呈现。我认为真正的创新和商业机会来自于控制平面。图 13展示了一个全局负载均衡系统。在本例中有一些不同的东西:

全局负载均衡能做一些单一负载均衡器做不到的事情,例如:

全局负载均衡器要成为现实,他的数据平面必须具有强大的动态配置能力。请参考我的博客:Envoy's universal data plane API,以及 Service Mesh Data Plan vs Control Plan 。

6


结论,以及负载均衡器的未来


综上所述,本文的主旨:


总的说来,我认为这是计算器网络的奇迹年代。多数系统开始向开源和软件方向转变,极大的提高了迭代速度。未来,分布式系统又向无服务器计算进军,底层网络和负载均衡系统的复杂性也势必齐头并进,水涨船高。

看了以上关于负载均衡那点事儿的一些浅见,如果大家还有什么地方需要了解的可以在亿速云行业资讯里查找自己感兴趣的或者找我们的专业技术工程师解答的,亿速云技术工程师在行业内拥有十几年的经验了。

 

 

推荐阅读:
  1. 浅谈centos启动那点事儿
  2. 关于数据传输中加密解密那点事儿(二)

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

负载均衡 那点

上一篇:HAproxy+Keepalived负载均衡-高可用web站详细流程介绍

下一篇:为什么Haproxy负载均衡反向代理要比nginx好

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》