您当前的位置:首页 > 电脑百科 > 程序开发 > 算法

5种常用的负载均衡算法

时间:2023-08-20 12:35:04  来源:微信公众号  作者:猿java

在 什么是网关 文章中,我们介绍过,网关最重要的功能之一就是负载均衡,那么,什么是负载均衡?负载均衡有哪些方式?今天我们就来聊一聊。

一、定义 

负载均衡(Load Balancing)是一种计算机网络和服务器管理技术,旨在分配网络流量、请求或工作负载到多个服务器或资源,以确保这些服务器能够高效、均匀地处理负载,并且能够提供更高的性能、可用性和可扩展性。

二、负载均衡算法 

1.Round Robin-轮询

轮询,顾名思义,把请求按顺序分配给每个服务器,然后重复执行这个顺序,进行请求分配。如下图:

图片

如上图,有3台服务器,分别为服务器A、服务器B和服务器C,当客户端有请求过来时,请求会按照 A->B->C->A->B->C->… 这种轮询的顺序分配给各个服务器。

原理

  1. 服务器列表:维护一个服务器列表,有服务器加入/剔除时,相应的更新服务器列表;

  2. 服务器游标:记录需要处理下一个请求的服务器;

  3. 请求分发:新请求到达,选择当前服务器来处理该请求,然后服务器游标+1;

  4. 循环:不断重复步骤3,以确保每个服务器都有机会处理请求;

算法实现

方法1:

轮询算法的实现非常简单,可以定义一个服务器的列表和当前服务器指针,如下伪代码:

# 服务器列表servers = ["ServerA", "ServerB", "ServerC"]# 当前服务器current_server = 0# 轮询算法if(req):    # 选择当前服务器来处理请求    process_request(servers[current_server])    # 将当前服务器移到服务器列表的末尾
    if current_server == length(servers):        current_server = 0    else:      # 指针+1      current_server += 1

当客户端有新的请求到达时,负载均衡器会选择服务器指针(current_server)指向的服务器来处理请求,然后将当前服务器指针移到下一个服务器(current_server += 1), 如果 current_server=服务器总数,则把current_server设置为0,进行下一场轮询。

方法2: 循环列表

循环列表是一个环形数据结构,用于按照顺序循环遍历服务器列表。当指针指向列表的末尾时,指针会回到列表的开头,从而实现循环。如下伪代码:

servers = ["Server1", "Server2", "Server3"]  # 服务器列表current_index = 0  # 当前服务器的索引
def get_next_server(self):      if not self.servers:          return None      # 获取当前服务器      current_server = self.servers[self.current_index]      # 更新索引,移到下一个服务器      self.current_index = (self.current_index + 1) % len(self.servers)
      return current_server
# 创建一个包含服务器的列表servers_list = ["ServerA", "ServerB", "ServerC"]

# 模拟请求的处理过程if(req):  # 假设有5个请    next_server = get_next_server()    if next_server is not None:        process_request(next_server)    else:        print("No avAIlable servers.")

优缺点

优点:简单,实现成本低;

缺点:

  1. 无法根据服务器的负载情况来分配请求,当服务器的负载不均衡时,轮询算法无法自动调整。

  2. 当服务器down机了,轮询算法无法自动剔除该服务器,导致请求会被转发到down机的服务器上。

适用场景

对服务器没有什么特别的要求,就可以采用轮询算法,比如:Nginx 默认适用的就是轮询算法。

2.Weighted Round Robin - 加权轮询

加权轮询算法是轮询算法的一种改进,只不过在负载时会根据服务器的权重来分配请求,权重越大,分配的请求就会越多。如下图:

图片

算法实现

实现算法和轮询很类似,只不过会根据权重在列表中放置不同比例的服务器,同时定义一个服务器的列表和当前服务器指针,如下伪代码:

# 服务器列表servers = ["ServerA", "ServerA", "ServerA", "ServerB","ServerB", "ServerC"]# 当前服务器current_server = 0# 轮询算法if(req):    # 选择当前服务器来处理请求    process_request(servers[current_server])    # 将当前服务器移到服务器列表的末尾
    if current_server == length(servers):        current_server = 0    else:      # 指针+1      current_server += 1

当客户端有新的请求到达时,负载均衡器会选择服务器指针(current_server)指向的服务器来处理请求,然后将当前服务器指针移到下一个服务器(current_server += 1), 如果 current_server=服务器总数,则把current_server设置为0,进行下一场轮询。

优缺点

优点:可以人为配置权重,为处理能力强的服务器配置高的权重,处理能力弱的配置低的权重,从而实现负载均衡。

缺点:无法应对服务器动态变化的情况,比如:服务器down机了,无法自动剔除该服务器,导致请求会被转发到down机的服务器上。

适用场景

服务器的处理能力不一致,可以采用加权轮询算法。

比如:有3台服务器,服务器A(4C8G,4个CPU,8G内存),服务器B(2C4G,2个CPU,4G内存),服务器C(1C2G,1个CPU,2G内存),那么可以配置服务器A的权重为4,服务器B的权重为2,服务器C的权重为1。

3.Least Connections - 最小连接数

最小连接数,是指把请求分配给当前连接数最少的服务器,以确保负载更均匀。如下图:

图片

上图中有 3台服务器,服务器A(连接数10)、服务器B(连接数100)和服务器C(连接数1000),连接数最少的服务器A分配的Req比其他服务器多。

原理

  1. 维护一个所有服务器和连接数的字典(Map);

  2. 当新的请求到达时,负载均衡器会检查服务器列表中当前连接数最少的服务器;

  3. 请求将被分配给具有最少连接数的服务器,处理请求后该服务器的连接数+1;

  4. 如果有多台服务器具有相同的最小连接数,算法可以使用其他标准来选择其中一台,如加权等。

算法实现

如下伪代码:

# 创建一个包含服务器及其连接数的字典servers = {"Server A": 5, "Server B": 3, "Server C": 4}

def get_server_with_least_connections():  # 找到当前连接数最少的服务器  min_connections = min(servers.values())
  # 找到具有最小连接数的服务器  for server, connections in servers.items():    if connections == min_connections:      return server
# 选择连接数最少的服务器def assign_request(self):  # 获取具有最小连接数的服务器  server = get_server_with_least_connections()  if server is not None:    # 模拟分配请求给服务器,增加连接数    self.servers[server] += 1    return server  else:    return "No available servers."
# 模拟请求的处理过程if req:  # 假设有请求  assigned_server = load_balancer.assign_request()

优缺点

优点:

  • 动态负载均衡:它根据服务器的当前负载情况来做出决策,这使得它能够有效地分配请求给当前连接数最少的服务器,从而确保了服务器资源的最佳利用。

  • 适应性强:这个算法适用于服务器性能不均匀的情况,因为它关注的是连接数,而不是服务器的硬件配置或性能评估。

  • 避免过载:通过将新请求分配给连接数最少的服务器,”最小连接数”算法有助于防止某些服务器被过度加载,从而提高了系统的稳定性和性能。

  • 自动恢复:如果某台服务器由于故障或重启而导致连接数清零,该算法会自动开始将新请求分配给该服务器,以实现自动恢复。

缺点:

  • 连接数不一定代表负载:”最小连接数”算法假设连接数与服务器的负载成正比,但这并不总是准确。有时候,某台服务器的连接数可能很高,但仍然能够处理更多的请求,而另一台连接数较低的服务器可能已经达到了其性能极限。

  • 不适用于长连接:如果服务器上有大量长期活跃的连接,例如WebSocket连接,该算法可能不太适用,因为长连接不同于短暂的HTTP请求,连接数的统计可能会产生误导。

  • 无法解决服务器性能差异:虽然”最小连接数”算法可以平衡连接数,但它无法解决服务器硬件性能差异的问题。在这种情况下,可能需要其他负载均衡算法,如加权轮询,来更好地适应性能差异。

适用场景

通过服务器连接数来做负载均衡的场景。到目前为止,还没有遇到生产上使用这种算法的场景。

4.IP/URL Hash - IP/URL 散列

IP/URL 散列算法是一种根据客户端 IP 地址或 URL 来分配请求的负载均衡算法,这样相同的IP或者URL就会负载到相同的服务器上。

原理

  • 将客户端 IP 地址或 URL 散列到服务器列表中,

  • 然后将请求分配给散列值对应的服务器。

如下图:有3台服务器,分别为服务器A、服务器B和服务器C,当相同IP的客户端请求会被负载到形同的服务器列中。

图片

优缺点

优点:

  • 稳定性:IP/URL Hash 算法可以确保相同的客户端请求总是被分发到相同的服务器上。这可以提高应用程序的稳定性,因为客户端的会话数据在同一服务器上保持一致。

  • 适用于会话保持:当应用程序需要在多次请求之间保持会话状态时,IP/URL Hash 算法非常有用。客户端在一次请求中选择的服务器会在后续请求中保持一致,确保会话数据不会丢失。

  • 负载均衡:IP/URL Hash 算法可以将特定的客户端请求均匀地分配到多个服务器上,从而实现基本的负载均衡,避免了某些服务器被过度请求。

缺点:

  • 不适用于动态环境:IP/URL Hash 算法基于客户端的 IP 地址或 URL,一旦客户端 IP 或请求的 URL 发生变化,请求可能会被分配到不同的服务器上,导致会话数据丢失或不一致。

  • 不考虑服务器负载:IP/URL Hash 算法不考虑服务器的当前负载情况。如果某个服务器的负载过高,IP/URL Hash 无法动态地将请求分发到负载较低的服务器上。

适用场景

静态环境:在静态环境中,即客户端的 IP 地址或请求的 URL 不经常变化的情况下,IP/URL Hash 算法可以提供稳定的负载均衡。

少数服务器的负载均衡:当服务器数量相对较少且不太容易动态扩展时,IP/URL Hash 算法可以用于基本的负载均衡。

5.Least Response Time - 最短响应时间

最短响应时间就是指:处理请求的响应时间最少的服务器,获取的请求就越多。直白讲就是随速度快,随就干的多。如下图:

图片

适用场景

负载均衡的所有服务器,处理能力相差比较大。比如:有3台服务器,服务器A(4C8G,4个CPU,8G内存),服务器B(2C4G,2个CPU,4G内存),服务器C(1C2G,1个CPU,2G内存), 那么就可以采用这种算法,这样可以根据服务器的处理来实现动态负载。

优缺点

优点:可以充分发挥各个服务器的性能,提高服务器的利用率。

缺点:饥饿问题。比如,服务器A的性能最好,处理速度最快,那么所有的请求都会被分配到服务器A,这样服务器B和服务器C就会一直处于饥饿状态,无法处理请求。这样也就会产生不公平。

算法实现

如下伪代码:记录每台服务器以及响应时间,然后找到响应时间最短的服务器,将请求分配到该服务器上。

# 服务器列表,每个服务器表示为一个字典,包含服务器的唯一标识符和响应时间servers = [    {"id": "serverA", "response_time": 10},    {"id": "serverB", "response_time": 30},    {"id": "serverC", "response_time": 100},    # 添加更多服务器]
# 找到响应时间最短的服务器def find_least_response_time_server(servers):
    # 初始选择第一个服务器为最短响应时间服务器    least_response_time_server = servers[0]
    # 遍历服务器列表,找到最短响应时间的服务器    for server in servers:        if server["response_time"] < least_response_time_server["response_time"]:            least_response_time_server = server
    return least_response_time_server
# 客户端请求到来时,选择最短响应时间的服务器def handle_client_request():    least_response_time_server = find_least_response_time_server(servers)    if req:      least_response_time_server.handle_client_request()

需要说明的是:这只是一个简单的示例,实际的负载均衡系统可能需要更复杂的逻辑,包括定期更新服务器的响应时间、处理服务器故障等。此外,要将这种算法应用于实际生产环境,可能需要使用专门的负载均衡软件或硬件,这些工具可以自动管理服务器并提供更多功能。

适用场景

交通控制系统:在城市交通控制系统中,需要及时响应交通信号、路况和车辆检测等信息。最短响应时间算法可以帮助确保交通信号及时适应交通流量的变化。

三、总结 

本文分析了5种常见的负载均衡算法,算法的实现都比较简单,在实际的生产环境中,我们可以根据自己的业务场景来选择合适的负载均衡算法。

另外,除了上面 5种算法外,还有一种其他的负载均衡算法,比如:

一致性哈希:Consistent Hashing,可以参考文章:hash & 一致性hash,如何选择?

加权最少连接:Weighted Least Connections,在Weighted Least Connections基础上再加权重。

在实际生产中,我们可能并不需要自己去实现这些算法,而会选择使用一些现有的框架,比如:nginx、lvs、haproxy等, 但是万变不离其宗,了解这些负载均衡算法可以帮组我们更好的去理解框架。



Tags:算法   点击:()  评论:()
声明:本站部分内容及图片来自互联网,转载是出于传递更多信息之目的,内容观点仅代表作者本人,不构成投资建议。投资者据此操作,风险自担。如有任何标注错误或版权侵犯请与我们联系,我们将及时更正、删除。
▌相关推荐
诱导付费、自动扣费……微短剧被质疑借助算法精准“围猎”老年人
诱导付费、自动扣费、重复收费&hellip;&hellip;聚焦身边的消费烦心事⑦丨一些微短剧被质疑借助算法精准“围猎”老年人中工网北京3月31日电(工人日报&mdash;中工网记者刘兵)...【详细内容】
2024-04-01  Search: 算法  点击:(5)  评论:(0)  加入收藏
分析网站SEO快速排名算法对网站具体的影响效果
亲爱的朋友们,今天我想和大家分享一个我们都关心的话题&mdash;&mdash;网站SEO快速排名算法对网站我们身处一个信息爆炸的时代,如何在海量的信息中脱颖而出,成为了一个我们不得...【详细内容】
2024-03-28  Search: 算法  点击:(12)  评论:(0)  加入收藏
当prompt策略遇上分治算法,南加大、微软让大模型炼成「火眼金睛」
近年来,大语言模型(LLMs)由于其通用的问题处理能力而引起了大量的关注。现有研究表明,适当的提示设计(prompt enginerring),例如思维链(Chain-of-Thoughts),可以解锁 LLM 在不同领域的...【详细内容】
2024-03-12  Search: 算法  点击:(12)  评论:(0)  加入收藏
谷歌宣布更新搜索算法:打击AI生成内容,提高搜索结果质量
IT之家 3 月 6 日消息,谷歌于当地时间 5 日发文宣布,针对用户对搜索结果质量下降的反馈,将对算法进行调整,旨在打击 AI 生成的内容以及内容农场等垃圾信息,使用户能够看到更多“...【详细内容】
2024-03-06  Search: 算法  点击:(37)  评论:(0)  加入收藏
小红书、视频号、抖音流量算法解析,干货满满,值得一看!
咱们中国现在可不是一般的牛!网上的网友已经破了十个亿啦!到了这个互联网的新时代,谁有更多的人流量,谁就能赢得更多的掌声哦~抖音、小红书、、视频号,是很多品牌必争的流量洼地...【详细内容】
2024-02-23  Search: 算法  点击:(12)  评论:(0)  加入收藏
雪花算法详解与Java实现:分布式唯一ID生成原理
SnowFlake 算法,是 Twitter 开源的分布式 ID 生成算法。其核心思想就是:使用一个 64 bit 的 long 型的数字作为全局唯一 ID。在分布式系统中的应用十分广泛,且 ID 引入了时间戳...【详细内容】
2024-02-03  Search: 算法  点击:(50)  评论:(0)  加入收藏
简易百科之什么是搜索引擎的PageRank算法?
简易百科之什么是搜索引擎的PageRank算法?在互联网时代,搜索引擎是我们获取信息的重要工具。而PageRank算法则是搜索引擎的核心技术之一,它决定了网页在搜索结果中的排名。那么...【详细内容】
2024-01-24  Search: 算法  点击:(49)  评论:(0)  加入收藏
PageRank算法揭秘:搜索引擎背后的魔法师的工作原理
PageRank(PR)算法是由谷歌创始人之一的拉里&middot;佩奇LarryPage命名的一种衡量网站页面重要性的方法。根据谷歌的说法,PageRank通过计算页面链接的数量和质量来粗略估计分...【详细内容】
2024-01-23  Search: 算法  点击:(44)  评论:(0)  加入收藏
程序开发中常用的十种算法,你用过几种?
当编写程序时,了解和使用不同的算法对解决问题至关重要。以下是C#中常用的10种算法,每个算法都伴随着示例代码和详细说明。1. 冒泡排序 (Bubble Sort):冒泡排序是一种简单的比...【详细内容】
2024-01-17  Search: 算法  点击:(44)  评论:(0)  加入收藏
百度最新的搜索引擎算法是什么样的?
百度搜索引擎算法是百度用来决定网页排名的算法。它是百度搜索技术的核心,也是百度作为全球最大的中文搜索引擎的基石。随着互联网的发展和用户需求的不断变化,百度搜索引擎算...【详细内容】
2024-01-10  Search: 算法  点击:(86)  评论:(0)  加入收藏
▌简易百科推荐
小红书、视频号、抖音流量算法解析,干货满满,值得一看!
咱们中国现在可不是一般的牛!网上的网友已经破了十个亿啦!到了这个互联网的新时代,谁有更多的人流量,谁就能赢得更多的掌声哦~抖音、小红书、、视频号,是很多品牌必争的流量洼地...【详细内容】
2024-02-23  二手车小胖说    Tags:流量算法   点击:(12)  评论:(0)  加入收藏
雪花算法详解与Java实现:分布式唯一ID生成原理
SnowFlake 算法,是 Twitter 开源的分布式 ID 生成算法。其核心思想就是:使用一个 64 bit 的 long 型的数字作为全局唯一 ID。在分布式系统中的应用十分广泛,且 ID 引入了时间戳...【详细内容】
2024-02-03   一安未来  微信公众号  Tags:雪花算法   点击:(50)  评论:(0)  加入收藏
程序开发中常用的十种算法,你用过几种?
当编写程序时,了解和使用不同的算法对解决问题至关重要。以下是C#中常用的10种算法,每个算法都伴随着示例代码和详细说明。1. 冒泡排序 (Bubble Sort):冒泡排序是一种简单的比...【详细内容】
2024-01-17  架构师老卢  今日头条  Tags:算法   点击:(44)  评论:(0)  加入收藏
百度推荐排序技术的思考与实践
本文将分享百度在推荐排序方面的思考与实践。在整个工业界的推广搜场景上,特征设计通常都是采用离散化的设计,需要保证两方面的效果,一方面是记忆,另一方面是泛化。特征都是通过...【详细内容】
2024-01-09  DataFunTalk  微信公众号  Tags:百度推荐   点击:(73)  评论:(0)  加入收藏
什么是布隆过滤器?如何实现布隆过滤器?
以下我们介绍了什么是布隆过滤器?它的使用场景和执行流程,以及在 Redis 中它的使用,那么问题来了,在日常开发中,也就是在 Java 开发中,我们又将如何操作布隆过滤器呢?布隆过滤器(Blo...【详细内容】
2024-01-05  Java中文社群  微信公众号  Tags:布隆过滤器   点击:(87)  评论:(0)  加入收藏
面向推荐系统的深度强化学习算法研究与应用
随着互联网的快速发展,推荐系统在各个领域中扮演着重要的角色。传统的推荐算法在面对大规模、复杂的数据时存在一定的局限性。为了解决这一问题,深度强化学习算法应运而生。本...【详细内容】
2024-01-04  数码小风向    Tags:算法   点击:(89)  评论:(0)  加入收藏
非负矩阵分解算法:从非负数据中提取主题、特征等信息
非负矩阵分解算法(Non-negativeMatrixFactorization,简称NMF)是一种常用的数据分析和特征提取方法,主要用于从非负数据中提取主题、特征等有意义的信息。本文将介绍非负矩阵分解...【详细内容】
2024-01-02  毛晓峰    Tags:算法   点击:(62)  评论:(0)  加入收藏
再谈前端算法,你这回明白了吗?
楔子 -- 青蛙跳台阶一只青蛙一次可以跳上一级台阶,也可以跳上二级台阶,求该青蛙跳上一个n级的台阶总共需要多少种跳法。分析: 当n=1的时候,①只需要跳一次即可;只有一种跳法,即f(...【详细内容】
2023-12-28  前端爱好者  微信公众号  Tags:前端算法   点击:(107)  评论:(0)  加入收藏
三分钟学习二分查找
二分查找是一种在有序数组中查找元素的算法,通过不断将搜索区域分成两半来实现。你可能在日常生活中已经不知不觉地使用了大脑里的二分查找。最常见的例子是在字典中查找一个...【详细内容】
2023-12-22  小技术君  微信公众号  Tags:二分查找   点击:(78)  评论:(0)  加入收藏
强化学习算法在资源调度与优化中的应用
随着云计算和大数据技术的快速发展,资源调度与优化成为了现代计算系统中的重要问题。传统的资源调度算法往往基于静态规则或启发式方法,无法适应动态变化的环境和复杂的任务需...【详细内容】
2023-12-14  职场小达人欢晓    Tags:算法   点击:(164)  评论:(0)  加入收藏
站内最新
站内热门
站内头条