百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术资源 > 正文

秃头大佬用5000字带你把负载均衡功能的高可扩展性给讲透彻!

off999 2025-01-24 13:29 19 浏览 0 评论

高可扩展性

可扩展性直接影响业务的服务能力和应用规模。

当业务容量达到目前系统的容量极限时,我们通常有两种选择:一种是迁移业务到性能更好、容量更大的系统中;另一种是扩容当前系统的容量。

显然,迁移方案不仅操作复杂、业务影响大,而且对于容量更大、性能更高的系统,其迁移成本可能会成倍增长。

如果服务具备高扩展能力,我们就能很容易地通过平滑扩容的方式提高当前系统的容量。

负载均衡服务作为业务流量的入口,对扩展性和伸缩性的要求比其他服务更高。下面将从负载均衡器、后端服务器两个角度讨论负载均衡系统的高可扩展性原理和实现方法。

3.3.1 扩展负载均衡器

1.通过DNS技术扩展负载均衡器

DNS是一种分布式网络目录服务,主要用于实现域名与IP地址的相互转换。DNS服务采用分层的管理方式,可以按照地域、运营商分层配置和查询,并通过缓存技术保证并发处理性能。在一个调度区域内,如果DNS记录的业务域名关联了多个IP地址,在用户请求DNS域名查询时,DNS可以通过轮询的策略从这些关联的IP地址中选择其中一个IP地址来响应用户的查询请求。

我们可以利用DNS分布式服务和轮询查询机制扩展负载均衡器。下面以如图3-11所示的实例进一步说明。假如爱奇艺的主页服务www.iqiyi.com部署在北京联通节点上,节点内部通过负载均衡将流量分发到后端服务器组上,每个负载均衡器为该业务分配一个业务VIP(VIP:1.1.1.1),每个VIP再通过DNS配 置 关 联 到 域 名 上 。 如 果 北 京 联 通 服 务 区 域 内 的 用 户 请 求 访 问www.iqiyi.com,则DNS将把该区域的解析结果1.1.1.1和2.2.2.2以轮询的方式响应给用户的DNS查询请求。当北京联通区域内的负载均衡器需要扩展时,我们只需要新增一台负载均衡器,并将其对应的新业务VIP关联到该区域的DNS服务上。此外,DNS还能为负载均衡器提供跨区域扩展能力。

比如,当北京联通区域不能继续扩容时,我们可以在上海电信新增DNS调度区域,并在该区域部署扩展负载均衡器。这样,访问www.iqiyi.com的用户流量将按照DNS配置分担到北京联通和上海电信两个节点,从而实现负载均衡的跨区域扩展。通过DNS技术扩展负载均衡器的优点是能对业务流量按区域和运营商进行灵活分配,但每次扩展负载均衡器都需要占用一个IP地址,且其中一个负载均衡器发生故障时要经过DNS缓存老化时间后才能摘除。所以,我们一般使用DNS服务对业务进行跨区域、运营商的分布式部署和异地容灾,很少直接使用DNS对负载均衡器进行扩展。

2.通过ECMP技术扩展负载均衡器

我们在讨论负载均衡器的高可用性时已经提到过ECMP技术。使用ECMP实现集群化除了能提高负载均衡服务的高可用性,还能赋予负载均衡服务可扩展能力。

图3-12所示为用两级ECMP网络对负载均衡器进行可扩展部署的网络拓扑结构。负载均衡器LB.1~LB.3和接入交换机(Switch)SW.1下联构成第一级负载均衡网络,可以实现把SW.1上的业务流量通过ECMP Network.B分摊到3个负载均衡器上,当LB.1~LB.3这组负载均衡器需要扩容时,只需要在ECMPNetwork.B中配置一台新的负载均衡器,即可把SW.1的业务流量由3台负载均衡器分摊变为由4台负载均衡器分摊。对于大部分业务,这样由第一级ECMP网络构成的负载均衡集群就可以满足业务扩展性需求。对于业务流量特别大的情况,我们可以进一步在接入交换机SW.1、SW.2上联和核心路由器RT.1中配置第二级ECMP Network.A,将核心路由器RT.1上的业务流量分摊到两个接入交换机SW.1和SW.2上,并进一步由第一级ECMP网络分摊到负载均衡器LB.1~LB.6上。

ECMP网络一般通过一致性哈希技术保证同一条数据流不被分发到不同的负载均衡器上,并且在添加或删除负载均衡器时,只影响该负载均衡器上的业务连接。

使用ECMP技术扩展负载均衡器的方法通常应用于IDC内部多个负载均衡器的水平扩展。这种方法使用等价路由原理把业务的VIP通过多台负载均衡器发布到外网,每个服务只需要占用一个IP地址,而且扩展方法简单、方便,所以被广泛应用于IDC内部负载均衡器和业务的部署。

3.通过负载均衡技术扩展负载均衡器(多级负载均衡)负载均衡器的一种常见部署方式是不同类型的负载均衡器级联部署,这种部署方式把一种负载均衡器作为另一种负载均衡器的后端服务器,利用前者的负载均衡能力实现后者的可扩展性和高可用性。

图3-13所示为通过负载的均衡技术扩展负载均衡器的典型网络拓扑结构。

由于四层负载均衡器是基于网络层协议的IP地址和传输层协议的端口信息工作的,性能远高于工作在应用层上的七层负载均衡器,因此将七层负载均衡器作为四层负载均衡器的后端服务器是合理的。最常用的四层负载均衡器是基于Linux Kernel实现的LVS,常见的七层负载均衡器有Nginx、HAProxy等支持反向代理的应用服务器。四层负载均衡器可提供多业务、多个IP地址接入能力,而七层负载均衡器则按照应用协议对业务流量做进一步精细化控制,如Nginx可以根据域名和URL把来自LVS同一个VIP的业务流量转发到不同后端服务器集群上。七层负载均衡器利用四层负载均衡器提供的健康检查服务实现平滑扩容和下线,四层负载均衡器则可以使用ECMP等技术实现集群化服务,从而保证了多级负载均衡系统的高可用性和高可扩展性。

虽然通过负载均衡集群扩展负载均衡器的方式增加了一层负载均衡转发,但四层负载均衡器和七层负载均衡器功能的互补作用可以增加业务配置的灵活性和负载均衡集群的利用率,所以这种负载均衡器的扩展方案被广泛应用于七层负载均衡器的集群化部署中。

4.通过Anycast技术扩展负载均衡器

使用Anycast技术可以实现把相同的业务VIP地址跨地域发布到不同的负载均衡集群上,不同用户的访问流量按照最优路径原则最终被路由到不同的负载均衡器上。所以,从原理上来讲,可以利用Anycast技术扩展负载均衡器。但Anycast在网络波动时可会把同一条业务流中的数据包发送到不同的服务器上,因此Anycast技术还只是主要应用于DNS服务、时间服务等无状态的业务上。我们将在3.4节进一步讨论Anycast技术。

3.3.2 扩展后端服务器

当负载均衡器需要扩展后端服务器(Real Server)时,我们如何把新的Real Server加入负载均衡转发列表中,并对当前的服务不产生影响呢?下面介绍一下实现该目的的两种机制。

1.配置文件重载机制(reload机制)

在之前的章节中,我们看到四层负载均衡器LVS使用keepalived.conf配置文件管理Real Server,七层负载均衡器Nginx则使用自己的配置文件管理RealServer。所以,当需要扩展Real Server时,首先需要把新的Real Server配置写入相应的配置文件,然后在运行的负载均衡服务不重启、不中断的前提下加载新的配置文件。所以,我们需要一种平滑重启机制,使得负载均衡器在服务运行中重新加载配置文件而不影响业务流量的转发。

Keepalived和Nginx都采用SIGHUP信号重新加载更新后的配置文件。

SIGHUP信号默认是在用户终端连接(正常或非正常)结束时发出的,通常在终端的控制进程结束时通知同一个终端内的各个作业与控制终端断开关联。当用户登录Linux时,系统会给用户分配一个终端。在这个终端下运行的所有程序,包括前台进程组和后台进程组,一般都属于这个终端。当用户退出Linux登录时,前台进程组和后台有终端输出的进程将会收到SIGHUP信号。

这个信号的默认行为是终止进程,因此前台进程组和后台有终端输出的进程就会终止。由于Keepalived或Nginx通常作为系统守护进程运行,守护进程会与终端脱离关系,所以SIGHUP信号的默认作用对守护进程就没有了意义。我们可以重新定义守护进程的意义,利用SIGHUP信号通知守护进程重新读取配置文件,并将文件加载到内存中。因此,对于使用配置文件管理的负载均衡配置,只需把扩展的Real Server更新到配置文件中,然后对负载均衡器进程发送SIGHUP指令即可。

下面以Nginx为例解释一下具体流程。Nginx的进程分为Master主进程和Worker工作进程,Master主进程主要管理事件信号的接收和分发,所有的请求处理都由Worker工作进程完成并返回结果。Nginx的平滑重启机制会先向Master主进程发送重启或重载配置文件信号,然后Master主进程告诉所有的Worker工作进程不再接收新的请求,并启动新的Worker工作进程,待旧的Worker工作进程处理完剩余工作并退出,就完成了平滑重启机制。

此外,Nginx除了支持平滑重启机制,还支持平滑升级机制。Nginx的平滑升级和平滑重启的过程有些区别,在平滑升级的过程中,涉及3个信号(USR2、WINCH和QUIT),首先发送USR2信号给原Master主进程,原Master主进程会额外启动一个Master主进程和若干个Worker工作进程,新旧Worker工作进程同时提供对外服务;然后发送WINCH信号给原Master主进程,原Worker工作进程停止服务并退出;最后发送QUIT信号给原Master主进程使之退出,只保留新的Master主进程和Worker工作进程,至此完成平滑升级。关于Nginx平滑升级更详细的内容介绍,读者可以参考Nginx文档(见链接[10])。

2.服务发现机制

服务发现机制广泛应用于微服务技术领域,用于解决在应用实例发生动态扩展、失败或升级时如何保证服务的可用性和一致性问题。服务发现的核心是一个服务登记表,该表是一个包含所有可用服务实例网络地址的数据库。当用户发起用户请求后,通过查询服务登记表获取一个可用的应用实例来处理用户请求。

图3-14所示为通过服务发现机制扩展Real Server的原理图。与之前的负载均衡网络结构相比,该原理图增加了服务发现组件,它包含服务登记服务器端和服务登记客户端。

服务登记客户端嵌入在Real Server内,负责向服务登记服务器端注册和实时更新自己的服务可用状态;服务登记服务器端负责处理负载均衡器对Real Server的查询,用户请求到达负载均衡器后,负载均衡器通过查询服务登记表,并按照一定的负载均衡策略选取其中一个可用的RealServer,将用户请求转发到该Real Server上进行处理。服务登记客户端与服务登记服务器端同步状态,这里可以使用自己注册的Self-Registration同步方式,也可以使用第三方的Third-Party Registration方式。

此外,利用服务发现机制还可以实现客户端负载均衡,即不需要使用服务器端的负载均衡器,用户程序直接查询服务登记表获取可用的Real Server列表,然后选择其中一个Real Server发起请求。这种模式更简单、灵活、直接,但是用户程序和服务登记程序强耦合,通用性差,开发、应用、维护较为困难,因此应用相对较少。

使用BGP Anycast实现多个IDC负载均衡和机房灾备

虽然使用VRRP或ECMP可以构建具有高可用性和高伸缩性的负载均衡集群,但这还只能是在同一个IDC内部保证负载均衡的可靠性和可伸缩性。如果IDC因电源、灾害等原因整体发生故障,如何保障应用服务的连续性?另外,为了提高服务质量、降低用户访问时延,应用服务和负载均衡可能部署在多个地区,如何管理不同地区的负载均衡集群,让用户始终能以最优的方式访问应用服务?本节介绍的Anycast技术为这些问题提供了一个很好的解决方案。

Anycast是一种网络寻址和路由方案,它允许一个IP地址同时配置在多个设备上,对一个特定用户,到达这些设备的路由是不同的。当数据包被转发时,路由器会为用户选择最优的路径。IPv6协议原生支持Anycast技术,所以支持IPv6 Anycast的网络只需要把负载均衡的VIP地址配置为IPv6 Anycast地址,就可以实现同一个IPv6协议网络内不同IDC之间的负载均衡。但是,IPv4协议本身不支持Anycast技术,而且IPv6 Anycast需要路由器、交换机支持。在IPv4协议网络或IPv6协议网络中,可以使用BGP(BorderGateway Protocol)(见链接[12])技术作为Anycast技术的替代方案。

我们把一个相同的单播地址分配给多个设备(这些设备一般分布在不同地区),并通过BGP对外宣告到达这些设备的不同路由。这样,不同设备配置了相同地址并对外宣告了该地址的多个路由,路由器会把这些路由看作到达同一个设备的不同路由,并在转发数据包时,根据路由算法选择用户到达目标地址代价最小的路由。当某个节点发生故障时,该节点的地址将被摘除,BGP会撤销发布到故障节点的路由,用户的数据包会被自动转发到其他可用节点。

图3-15所示为使用BGP Anycast实现多个IDC负载均衡和机房灾备的示意图。两个网络应用部署在不同IDC上,并通过负载均衡为用户访问提供服务。

两个IDC的负载均衡集群为该服务提供了同一个VIP,并通过BGP协议向外部网络通告了两条路由。当用户访问该VIP时,路由算法会为用户选择到达目标VIP最优的一条路径。比如,如果只考虑地理位置的距离因素,则路由器会将用户请求转发到距离用户最近的IDC,从而实现跨IDC的负载均衡。另外,当一个IDC发生故障时,配置在该IDC内负载均衡器上的VIP也会因故障变成不可用的状态,BGP协议感知到该IDC的VIP状态变化后,会自动撤销指向该IDC的路由,原来访问该IDC服务的用户会被路由到另一个次优的路由节点,从而实现机房故障的灾备。

需要注意的是,用户服务之间的Anycast路由可能会因为网络拥塞或网络拓扑的变化而改变,所以无法保证同一个用户的数据会始终转发到同一个负载均衡集群上。因此,Anycast主要用于基于无状态的UDP协议构建的服务,如DNS服务。另外,考虑到路由的相对稳定性,对于基于TCP协议的短连接服务,Anycast也有一定的应用价值。

本文给大家讲解的内容是负载均衡功能-高可扩展性

  • 下篇文章给大家讲解现有负载均衡器比较--四层负载均衡器

相关推荐

安装python语言,运行你的第一行代码

#01安装Python访问Python官方(https://www.python.org/),下载并安装最新版本的Python。确保安装过程中勾选“Addpython.exetoPAT...

Python推导式家族深度解析:字典/集合/生成器的艺术

一、为什么需要其他推导式?当你在处理数据时:o需要快速去重→集合推导式o要建立键值映射→字典推导式o处理海量数据→生成器表达式这些场景是列表推导式无法完美解决的,就像工具箱需要不同工...

别再用循环创建字典了!Python推导式让你的代码起飞

当同事还在用for循环吭哧吭哧创建字典时,我早已用推导式完成3个需求了!这个被90%新手忽视的语法,今天让你彻底掌握字典推导式的4大高阶玩法,文末彩蛋教你用1行代码搞定复杂数据转换!基础语法拆解#传...

什么是Python中的生成器推导式?(python生成器的好处)

编程派微信号:codingpy本文作者为NedBatchelder,是一名资深Python工程师,目前就职于在线教育网站Edx。文中蓝色下划线部分可“阅读原文”后点击。Python中有一种紧凑的语法...

Python 列表转换为字符串:实用指南

为什么在Python中将列表转换为字符串?Python列表非常灵活,但它们并非在所有地方都适用。有时你需要以人类可读的格式呈现数据——比如在UI中显示标签或将项目保存到CSV文件。可能还...

生成器表达式和列表推导式(生成器表达式的计算结果)

迭代器的输出有两个很常见的使用方式,1)对每一个元素执行操作,2)选择一个符合条件的元素子集。比如,给定一个字符串列表,你可能想去掉每个字符串尾部的空白字符,或是选出所有包含给定子串的字符串。列表...

python学习——038python中for循环VS列表推导式

在Python中,for循环和列表推导式(ListComprehension)都可以用于创建和处理列表,但它们的语法、性能和适用场景有所不同。以下是两者的详细对比:1.语法结构for循环使用...

python中列表推导式怎么用?(列表 python)

这个问题,我们不妨用近期很火的ChatGPT来试试,来看看人工智能是如何解答的?在Python中,列表解析是一种简洁的方法,用于生成列表。它是一种快速,简洁的方法,可以在一行代码中生成列表,而不需...

Python列表推导式:让你的代码优雅如诗!

每次写for循环都要三四行代码?处理数据时总被嵌套结构绕晕?学会列表推导式,一行代码就能让代码简洁十倍!今天带你解锁这个Python程序员装(偷)逼(懒)神器!一、为什么你需要列表推导式?代码...

python学习——038如何将for循环改写成列表推导式

在Python里,列表推导式是一种能够简洁生成列表的表达式,可用于替换普通的for循环。下面是列表推导式的基本语法和常见应用场景。基本语法result=[]foriteminite...

太牛了!Python 列表推导式,超级总结!这分析总结也太到位了!

Python列表推导式,超级总结!一、基本概念列表推导式是Python中创建列表的一种简洁语法,它允许你在一行代码内生成列表,替代传统的for循环方式。其核心思想是**"对可迭代对...

25-2-Python网络编程-TCP 编程示例

2-TCP编程示例应用程序通常通过“套接字”(socket)向网络发出请求或者应答网络请求,使主机间或者一台计算机上的进程间可以通信。Python语言提供了两种访问网络服务的功能。其中低级别的网络服...

python编程的基础与进阶(周兴富)(python编程基础视频)

前不久我发文:《懂了,if__name=='__main__'》。想不到的是,这个被朋友称之为“读晕了”的文章,其收藏量数百,有效阅读量竟然过万。所谓“有效阅读量”,就是读到尾部才退...

Python 闭包:深入理解函数式编程的核心概念

一、简介在Python编程领域,闭包(Closure)是一个既基础又强大的概念,它不仅是装饰器、回调函数等高级特性的实现基础,更是函数式编程思想的重要体现。理解闭包的工作原理,能够帮助开发者编写出...

Python小白逆袭!7天吃透PyQt6,独立开发超酷桌面应用

PythonGUI编程:PyQt6从入门到实战的全面指南在Python的庞大生态系统中,PyQt6作为一款强大的GUI(GraphicalUserInterface,图形用户界面)编程框架,为开...

取消回复欢迎 发表评论: