中电金信:技术实践|Flink多线程实现异构集群的动态负载均衡

news2024/10/6 14:31:51

导语:Apache Flink是一个框架和分布式处理引擎,用于对无界和有界数据流进行有状态计算。本文主要从实际案例入手并结合作者的实践经验,向各位读者分享当应用场景中异构集群无法做到负载均衡时,如何通过Flink的自定义多线程来实现异构集群的动态负载均衡。

● 1. 前言

● 2. 出现的问题与解决方案

 ● 2.1 出现问题

 ● 2.2 分析思路

 ● 2.3 解决方案

● 3. 技术架构

● 4. 建设成效

● 5. 结语

前言

在实时计算应用场景中经常会有对异构集群的实时调用需求,而当异构集群的服务由于机器配置、节点负载等原因无法做到负载均衡时,可以通过Flink的自定义多线程来实现对异构集群的动态负载均衡。           

下面举个例子:

文本内容鉴别、图片内容鉴别、图片OCR等特征生产需求,都需要和基于GPU部署的异构集群来交互。如果GPU集群机器配置无法统一,那么就会产生负载不均的情况。即:一个GPU集群中某些节点处理的快,某些节点处理的慢,处理慢的节点往往会导致大量的超时异常,从而引起整个作业的反压。

其流程图如下:

我们借助Flink分布式的先天优势,在任务中通过Thrift RPC调用模型服务,实时获取结果后再写到特征工程,以此来构建特征生成整个链路。

图片

出现的问题与解决方案

出现问题:

在模型服务中部署的若干个节点,节点和节点之间是完全独立的,每个节点上线/下线后都会将自己的状态更新到ZooKeeper。在Flink任务的每个subTask都会注册一个Watch,以便获取最新且可用的所有节点。对于流入到subTask的每条数据,都需要选择一个节点来完成数据的推理。

在前期,我们使用Random策略来选择节点,但是在使用过程中我们发现,如果服务端的一个模型节点性能变低,随之而来的就是数据推理的耗时变长,那么最终可能会导致Flink任务反压。而在服务端来看,很多模型节点并没有满负荷运行,但客户端反应出来的服务端性能却不够,处理完成的总QPS很低。

另外,在和模型服务通信的时候,我们采用的是同步策略,这对于一些推理耗时长、QPS高的任务来说,需要足够大的并发度才能完成数据请求。然而,这些任务的资源利用率较低,这也是生产环境的一大痛点。

图片

分析思路:

基于上图,我们作出如下分析:

在理想情况下,我们假设服务端有节点1、节点2、节点3,且3个节点性能都一致,每个节点都开32个并行度处理。假设每条数据处理耗时都是800ms,那么每个节点的处理能力应该是40条/s,三个节点满载的情况下处理能力应该是120条/s。

而在实际生产环境下,服务端部署的机器各个节点之间处理能力是有差异的,导致其出现差异的原因主要有三点。

 GPU物理机器有多种规格,性能之间差别较大,在进行部署时很难确保将节点部署在同一批机器上;

 一台机器上混部多种模型服务,相互之间会有影响;

 部分节点所在机器网络、磁盘等出现故障也会导致出现差异。

例如节点1和节点2部署在高性能机器上,节点并行度是32,单条数据处理耗时是800ms。节点3部署在低性能机器上,节点并行度是32,单条数据处理耗时2400ms,那么节点3的处理能力可以看作为13.3条/s。同样采用随机选择节点的策略,倘若一秒总共发送了40条数据,对于节点3来说就已经达到性能瓶颈了。假设这个时候有更多的数据选择到了节点3进行处理,就只能在服务端的队列进行排队,而如果这个队列满了就会拒绝连接。

随着任务的运行,节点3的等待队列数据会越来越多,客户端从发送请求到返回结果的耗时也会随之越来越大。这时一旦有subTask选择了这个节点,那么这个subTask就需要等待比较长的时间来完成这次的请求。在这个过程中,如果上游数据还在源源不断的流入,那么就会造成subTask的InputChannel慢慢被耗尽,随后公共Buffer Pool的空间也会被占满,进而导致subTask2卡死。又因为上游算子使用了Rebalance,最终会把整个Flink任务卡死。

图片

这是一个典型的木桶效应,在实际应用场景中,一旦有个别节点性能差或者出现故障,就会影响整个任务的稳定性。

解决方案:

在分析事故出现的原因后,我们提出给每个节点配置一个权重,模型节点定期将权重数值上报到ZooKeeper,客户端再通过权重来给每个节点分配相应的流量。这个想法很好,也在实践过程中取得了一定的效果,但是它有一个小问题:这样做会导致每个节点的流量一直抖动,抖动的频次和上报权重的时间呈正相关的关系,而且从监控来看,这样做也会导致处理的总数据量不太稳定。

图片

图片

在问题初步得到缓解后,我们开始思考是不是还有其他更好的方式可以解决这个事情。已知模型节点慢了会卡死一个subTask,而这个subTask本质是一个Slot,也就是一个线程,那么我们是不是可以借用多线程的方式来解决这个问题?带着这个思考,我们又尝试了另外两种解决方式:Async I/O和多线程方案。

■ Async I/O方案

Flink 在1.2版本中引入Async I/O,其主要目的是为了解决与外部系统交互时网络延迟成为系统瓶颈的问题。通过暴露出来的API,我们可以设置最大的操作数,简单理解为Slot中异步请求的最大并发数量。测试的时候我们准备了三个节点,一个节点处理耗时2000ms,另外两个节点处理耗时500ms。

任务在刚启动的几分钟内运行还比较正常,之后处理速度较慢节点的服务端队列堆积长度开始变得越来越大,最后稳定在150左右,与此同时超时失败率也开始随之升高。我们可以看到,通过这种方式虽然可以很好的解决因为快慢节点导致反压卡死和资源利用率问题,但是仍然无法解决流量分配的问题。

图片

图片

■ 多线程方案

我们在每个Slot内部实现一个生产者-消费者模型,再创建和模型节点相同数量的线程,让每个线程固定的请求一个节点,就算这个节点卡死或者处理速度缓慢,也只会影响当前线程,对整个subTask的影响有限。

图片

如上图所示,一个Slot内包含多个线程,个别线程对应的Service节点出现问题不会影响其它线程的消费。通过这种方式可以实现自适应的流量分发策略,每个线程对应一个服务端Pod,这种线程自适应阻塞的方式可以实现慢的节点少消费,快的节点多消费的目的。

在Flink以Slot为最小资源粒度情况下再进行细化,从Slot中开启若干个线程能够增大并发度,从而减少整体Slot数量,在降低资源的同时提高资源利用率。

技术架构

在Flink任务使用多线程的方案来解决RPC通信负载均衡的问题,编程模型需要做相应的改造,具体改造如下图:

图片

图片

建设成效

通过前后数据对比,我们发现在采用多线程方案后,效果还是很明显的。通过下图所示的服务端处理耗时这个指标我们可以看出以125.172结尾的节点处理耗时在1.7s左右,在流量分发数量指标可以看到分配给它的流量在5条/s左右;160.25的节点处理耗时在0.14s左右,分配的流量在58条/s左右,整体符合预期。

图片

图片

同时,为了保证整个服务的稳定性,我们增加了一些监控指标,如:缓存队列长度、模型失败率、链路耗时、写特征失败率等。

图片

结语

本文主要介绍了Flink在异构集群调用的时候,如果出现服务端无法分发流量的情况,在客户端可以通过多线程的方式实现流量的动态负载均衡,这样做可以帮助服务端兼容高低配机型,提升机器利用效能。不过,需要特别指出的是本文中使用的多线程算子是Stateless(无状态)的,对于有状态的算子还需要酌情考虑。另外,如果服务端是可以自主分配节点的组件时,可以选择使用Async I/O方案。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/880363.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

LangChain入门:构建LLM驱动的应用程序的初学者指南

LangChain & DemoGPT 一、介绍 你有没有想过如何使用大型语言模型(LLM)构建强大的应用程序?或者,也许您正在寻找一种简化的方式来开发这些应用程序?那么你来对地方了!本指南将向您介绍LangChain&#x…

Jquery 复选框点击生成标签 源代码

html <!DOCTYPE html> <html><head><meta charset"utf-8"><title>服务资源管理</title><link rel"stylesheet" type"text/css" href"../lib/layui/css/layui.css" /><link rel"st…

从零搭建vue + element-plus 项目

目录 从零搭建vue element-plus 项目 环境安装 安装项目 安装命令如下&#xff1a; 选择配置如下&#xff1a; 安装插件与启动服务 安装element框架 使用element框架 测试element是否安装成功 环境判断 安装插件 使用插件 配置变量 暴漏变量 测试…

菜单和内容滚动的联动原理及代码

之前写代码有个需求&#xff1a;左侧是一个菜单&#xff0c;右边是内容&#xff0c;点击左侧菜单右边内容滚动到对应位置&#xff0c;右边内容滚动到某位置时&#xff0c;左侧菜单也会选中对应的菜单项。UI如下&#xff1a;这是大多网站的移动端都会有的需求。 解决方案一&…

Presto之Union算子的实现

一. 前言 在Presto中&#xff0c;Union的算子包括自动去重的Union操作和不去重的Union All操作。本文主要简述在Presto中Union All算子是如何实现和Union算子中是如何实现数据去重的。 二. Presto之Union的实现 1. 首先在g4中将sql的union关键词与setOperation进行绑定 2. AstB…

css 利用 linear-gradient 实现条纹背景

1. 水平条纹背景 当给背景设置渐变效果时&#xff0c;默认的渐变方向是垂直由上到下的&#xff0c;效果如下&#xff1a; {background: linear-gradient(#aaa, #ddd);} 尝试拉近色标的距离&#xff0c;会发现渐变区域变小了&#xff1a; {background: linear-gradient(#aaa 40…

Spring Security6 最新版配置该怎么写,该如何实现动态权限管理

Spring Security 在最近几个版本中配置的写法都有一些变化&#xff0c;很多常见的方法都废弃了&#xff0c;并且将在未来的 Spring Security7 中移除&#xff0c;因此又补充了一些新的内容&#xff0c;重新发一下&#xff0c;供各位使用 Spring Security 的小伙伴们参考。 接下…

Android控件【Notification】

文章目录 Notification与NotifactionManager创建一个NotificationManager使用Builder构造器来创建Notification对象 NotificationChannel通知重要程度设置&#xff0c;NotificationManager类中 Notification&#xff08;通知&#xff09;常见方法说明注意项目结构主要代码 Noti…

国产DSP,经典之作,C2000,QX320F280049

特性&#xff1a; 1、替代TI 的 TMS320F280049 2、独立双核&#xff0c;主频400MHz 3、单精度浮点运算&#xff0c;三角函数运算 4、Flash 1MB&#xff0c;SRAM 1MB 5、12bit ADC&#xff0c;采样率 3.45MSPS 6、16个高分辨率 ePWM 优点&#xff1a; 1、主频400MHz&#xff0c…

clion2020.3配置clang-format

标题clion 启用clang-format 文件->设置->编辑器->代码样式. 为了保持原有代码风格不变&#xff0c;可以把原始的配置风格先导出&#xff0c;最好直接保存到自己的工程下&#xff0c;.clang-format是隐藏文件&#xff0c;需要用ctrlH才能看到 文件->设置->编辑…

i++和++i在操作数栈和局部变量表的分配

1、执行运算指令时&#xff0c;压入操作数栈的顺序不受运算优先级影响 2、i 先将i值压入到操作数栈&#xff0c;再在局部变量表自增 3、i 先在局部变量表自增&#xff0c;再压入到操作数栈 记忆方法&#xff1a;i的先后&#xff0c;表示压入操作数栈的先后。 看如下例子&am…

从零实战SLAM-第七课(多视角几何)

在七月算法报的班&#xff0c;老师讲的蛮好。好记性不如烂笔头&#xff0c;关键内容还是记录一下吧&#xff0c;课程入口&#xff0c;感兴趣的同学可以学习一下。 --------------------------------------------------------------------------------------------------------…

Centos7 开机时遇到initramfs-xxx.img not found错误导致虚拟机无法开启问题处理

1、背景 一台运行在Esxi上面的VM重启后报initramfs-xxx.img not found错误。 按任意键后出现以下错误。 之前在运维Centos7的时候解决过Kernel panic - not syncing : VFS: Unable to mount root fs on unknown-block(0.0)错误&#xff0c;以为按照之前的解决方案&#xff0c;…

【删除vlan的方法】

提示错误 [SW1]undo vlan 10 Error: The VLAN has a L3 interface. Please delete it first. 解决办法 undo interface Vlanif10 #删除vlan 10下的接口 [SW1-GigabitEthernet0/0/1]dis this #删除下列的IP

vue3+ts使用antv/x6 + 自定义节点

使用 2.x 版本 x6.antv 新官网: 安装 npm install antv/x6 //"antv/x6": "^2.1.6",项目结构 1、初始化画布 index.vue <template><div id"container"></div> </template><script setup langts> import { onM…

从鲁大师十五年,寻找软件的生存法则

千禧之年&#xff0c;国内互联网用户数量首次突破1000万大关&#xff0c;互联网的腾飞正式拉开序幕。 从彼时算起&#xff0c;中国互联网发展也不过23年&#xff0c;而我们记忆中那个摇着蒲扇的老头&#xff0c;却占据了其中关键的十五年。 这十五年中有太多曾经为人熟知的软件…

超强的Everything,吊打系统自带文件搜索功能!

目录 一、软件简介 二、软件下载 三、软件说明 一、软件简介 Everything是一款由David OReilly开发的电脑搜索软件&#xff0c;它可以帮助用户快速找到电脑上的文件和文件夹。与其他搜索工具不同的是&#xff0c;Everything使用了一种非常快速和高效的搜索算法&#xff0c…

小视频AI智能分析系统解决方案

2022下半年一个项目&#xff0c;我司研发一个基于接收小视频录像文件和图片进行算法分析抓拍的系统&#xff0c;整理了一下主要思想如下&#xff1a; 采用C开发一个AI识别服务&#xff0c;该服务具有如下功能: 创建各类算法模型服务引擎池&#xff0c;每类池内可加载多个模型…

vue自定义指令--动态参数绑定

在企业微信侧边栏应用中&#xff0c;给dialog添加了拖拽功能&#xff0c;但是因为dialog高度超过了页面高度&#xff0c;所以高度100%时拖拽有个bug--自动贴到窗口顶部而且企业侧边栏宽高都有限制&#xff0c;拖拽效果并不理想&#xff0c;所以就想缩小dialog再进行拖拽。 拖拽…

全网最新超详细的C盘扩容(2023年),比如把D盘内存分给C盘

文章目录 1. 引入问题2. 磁盘分区3. 磁盘扩容4. 使用DiskGenius的注意事项 1. 引入问题 今天打开电脑&#xff0c;发现C盘爆红&#xff0c;如下图所示&#xff1a; 此时&#xff0c;我就知道需要扩容。 2. 磁盘分区 我们在扩容C盘的前提&#xff0c;需要寻找其他可用空间较多…