前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >语言类算法服务负载均衡初探

语言类算法服务负载均衡初探

作者头像
云原生小白
发布2023-08-28 18:15:53
2980
发布2023-08-28 18:15:53
举报
文章被收录于专栏:LokiLoki

最近通过Nginx来反向代理一批大模型服务,遇到一个典型问题。默认的轮训负载均衡场景下,如果用户的每次请求到达算法服务时,由于不同的问题导致算法返回的Token长度不一致。就会出现某些算法Pod在上轮问答还没结束时收到了下次的请求。由于Nginx或负载均衡器上无法预测上游算法的Token长度,只能暴力的讲请求轮训分发到后端,长此以往,就导致后端算法服务随机出现阻塞的问题。

我原本是想利用ngx_http_dyups_module模块来开放一个URI来让后端算法根据当前的任务动态调整自己在Nginx Upstream上的权重,类似这样

GET http://nginx-serger:7080/dynamic?upstream=zone_for_backends&server=127.0.0.1:8080&weight=10&max_fails=5&fail_timeout=5

img_v2_07d6c717-021b-401c-a9de-9591fe2c8eeg

但这个方案无法在Kubernetes Ingress Nginx上实现,且在业务层有代码侵入到代码,虽然工作量不大,但感觉实践起来比较别扭。

转机,再一次意外的网上冲浪过程中,我发现Ingress Nginx上支持EWMA调度算法,虽然以前看过,但仅限于了解用来根据响应耗时来做负载均衡。仔细想了想,上面的问题本质上也是个长链接场景下的负载均衡问题。便在Ingress Nginx上开启了试下,果然Work! 之前多副本情况下算法服务的Pod CPU总是出现旱的旱死,涝的涝死的情况,开启之后整体来看,较为均衡。

image-20230608131148502

以下对我了解EWMA帮助比较大的文章,大家值得阅读

原文出处 https://linkerd.io/2016/03/16/beyond-round-robin-load-balancing-for-latency/

负载均衡是任何大规模软件部署的关键组成部分。但进行负载均衡的方法有很多,哪种方式最好呢?我们如何评估不同的选项?

在现代软件生态系统中,负载均衡起到了几个角色。首先,它是可扩展性的基础。软件被部署为多个相同的副本。我们通过部署额外的副本来“扩展”软件。流量必须在各副本间分配,而这个分配就是负载均衡。

负载均衡提供了另一个必要的特性:即弹性。直观地讲,一个具有弹性的系统是指,即使单个组件失败,也不会导致整个系统失败的系统。软件或者运行软件的硬件都会失败。通过只将流量分配给能够提供服务的实例,负载均衡使我们能够将多个可能出错的组件连接成一个具有弹性的系统。

我们可以将这种弹性模型进一步扩展,以应对分布式系统中的另一个不受欢迎的访问者:延迟。就像系统的组件可能会失败一样,它们也可能变慢。一个好的负载均衡器必须能够防止延迟,就像它防止失败一样。即使在存在慢副本的情况下,整个系统也必须保持快速。

这第三个标准比前两个微妙。从算法上讲,处理可扩展性和弹性是直接的:给定一组副本,将流量分配到所有活跃的副本,并不把流量分配给已经失败的副本。(我们暂时忽略评估副本健康状况的挑战。)对于延迟,情况就不那么明确了:给定一组以各种速度运行的副本,将负载分配给它们的最佳策略是什么?

在这篇文章中,我们使用三种算法进行了一个简单的实验:轮询、最少负载以及峰值指数加权移动平均(“Peak EWMA”)。这三种算法作为一个测试床,展示了正确或错误的负载均衡算法选择可能带来的影响。特别是,我们测试了这些算法处理组件延迟的有效性。

简单来说,这三种算法的行为如下:

  • 轮询:依次向每个副本分发请求 的计数,并向未完成请求最少的副本分配流量
  • 最少负载:维护对每个副本的未完成请求
  • 峰值EWMA:维护每个副本的往返时间的移动平均值,由未完成请求的数量加权,并向成本函数最小的副本分配流量。

在这三种算法中,轮询在实践中常见,大多数软件负载均衡器,包括Nginx和HAProxy,都支持。另外两种算法在实践中较少见,但在Twitter的客户端RPC库Finagle中,都有经过生产测试的实现。

请注意,对负载均衡策略的选择应根据您的具体业务需求和系统特性进行。不同的系统可能更适合使用不同的负载均衡策略。最好的方式是进行实验,看看在你的特定环境和工作负载下哪种策略效果最好。

实验设置

我们进行了一个简单的模拟实验,使用以下场景测量组件延迟对整个系统延迟的影响:

  • 11个后端服务器,每个服务器重放从生产系统捕获的延迟。此延迟分布的中位数为167ms,标准差为5ms,没有显著的峰值。
  • 一个客户端,以1000 qps的速度运行,平衡所有11个后端。
  • 运行总时间为一分钟。
  • 在开始后15秒,固定一个服务器的延迟为2秒,持续30秒,然后恢复正常。(这模拟了后端服务遭受糟糕的垃圾回收暂停或其他瞬态问题。)

我们使用基于Finagle编写的基础RPC客户端进行这些实验。

结果

实验结果如上图所示。y轴表示延迟,x轴(对数刻度)表示超过该延迟的延迟分布中的百分位数。

在面对慢服务器的情况下,三种算法的性能差异非常明显。轮询受影响最大,显示出在95百分位以上的慢速性能。最少负载表现得更好,保持快速性能直到99百分位,而峰值EWMA表现得更好,保持速度直到99.9百分位。

由于在分布式系统中,延迟和失败经常通过超时绑定在一起,我们也可以用失败来表达结果。如果我们系统的调用者使用1秒的超时,那么使用轮询的成功率大约是95%,使用最少负载的成功率是99%,而使用峰值EWMA的成功率是99.9%——这是一个显著的差异。

讨论

从三种算法中可以看出,轮询明显是表现最差的。在某些方面,这并不令人惊讶:因为它也是最简单的算法。

然而,轮询不仅仅是一个更糟糕的算法——它没有利用最少负载和峰值EWMA可以利用的信息。因为Finagle在OSI模型的第5层(“会话”层)上操作,它可以获取到队列深度和RPC延迟等信息。最少负载利用了队列深度,并显示出明显优于轮询的性能;峰值EWMA考虑了RPC延迟和队列深度,表现出更好的性能。这三个选项之间的差异并不仅仅是算法上的,而更多的是用来做负载均衡决策的信息的差异。

当然,在实践中,影响负载均衡性能的因素远不止算法的选择。在高并发下,实现可能性能较差。算法可能不适合某些类别的请求,如长轮询请求(在这种情况下,高延迟是预期的,而不是失败的症状)。算法可能不适合特定的客户端/服务器关系,例如高度不对称的副本数量。在这篇文章中,我们并没有试图提供全面的分析,并且只花费了最少的努力来控制这些变量。我们的意图仅仅是提供一个算法选择可能产生的差异的例子。

也就是说,Twitter的大规模生产实验已经验证了最少负载和峰值EWMA(以及其他负载均衡算法)的有效性,并且这些算法被大规模地用于支持Twitter今天的大部分基础设施。

结论

对于负载均衡高级连接(如RPC或HTTP调用)的系统,其中第5层信息(如端点延迟和请求深度)可用,当有慢速端点存在时,轮询负载均衡可能比其他算法表现得要差得多。通过使用可以利用第5层信息的算法,这些系统可能在面对慢速端点时显示出显著改善的性能。

如果上述结果适用于你的情况,你可能需要利用像最少负载和峰值EWMA这样的算法。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2023-06-08,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 云原生小白 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 实验设置
  • 结果
  • 讨论
  • 结论
相关产品与服务
负载均衡
负载均衡(Cloud Load Balancer,CLB)提供安全快捷的流量分发服务,访问流量经由 CLB 可以自动分配到云中的多台后端服务器上,扩展系统的服务能力并消除单点故障。负载均衡支持亿级连接和千万级并发,可轻松应对大流量访问,满足业务需求。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档