一种基于动态水位值的Flink调度优化算法(flink1.5以前),等同于实现flink的Credit-based反压原理

Netty:option和childOption参数设置说明 【代码】Netty:option和childOption参数设置说明 阅读详情

说明

首先说明,偶然看了个论文,发现 flink优化原来比我想象中的更简单,得到了一些启发,所以写下这篇帖子,供大家共同学习。
看到的论文是《计算机科学与应用》21年11月的一篇 名字就叫做 : 一种基于动态水位值的Flink调度优化算法。感兴趣的小伙伴可以自己看一下 ,很短没多少字。
但是 很离谱的是 这篇论文中的方法在flink1.5以后的反压机制中早就实现了,我不知道 这篇论文为什么能发表在21年11月的期刊上,也可能是我看论文看的不对?反正就当学习个人实现 flink1.5的反压机制更新了

1 flink反压介绍

1.1 介绍

首先说下flink反压,其实就是flink流式处理中一种动态反馈机制,一般是在实时数据处理的过程中,上游节点的生产速度大于下游节点的消费速度,提出反馈来提醒上游,下游消费不过来了。

如垃圾回收不及时或者停顿可能使得流入系统的数据快速堆积、大促或秒杀活动时出现的流量陡增等都会造成反压。如不对反压及时处理,将会使系统资源耗尽甚至导致系统崩溃。

1.2 大数据系统反压现状

现有大数据实时处理系统处理反压问题方面,Storm 是通过监控Bolt中的接收队列负载情况,如果超过高水位值就会将反压信息写到Zookeeper,Zookeeper上的watch会通知该拓扑的所有Worker都进入反压状态,最后Spout停止发送tuple。J Storm采用逐级降速的方式来处理反压,使用Topology Master替代Zookeeper来协调拓扑进入反压状态,效果较Storm更为稳定。Spark Streaming根据批处理时间(Batch Processing Time)和批次间隔(Batch Interval,即Batch Duration)的信息来动态调整系统的摄入速率,从而完成其反压工作。

在Flink优化方面,根据论文文献目前有几种:

  1. 使用Flink执行一种传统堆序优化后的算法Heap Optimize,增加了Flink的吞吐量 。
  2. 针对Flink默认的先来先服务的任务调度策略,通过资源感知,将待执行任务分配到最佳节点进行计算,优化了Flink的负载均衡。
  3. 根据任务间数据流的大小确定拓扑边的权重,以生成关键路径,大幅缩减了Flink节点间的通信开销。
  4. 把Flink从原来的CPU迁移扩展到异构的CPU-GPU集群,在并行计算、内存管理及通信策略方面极大地提高了Flink的计算能力。

目前诸多的研究当中没有Flink反压方面的问题,当Flink面临远端传输问题时,其所依托的Netty所采用的是一种静态的水位机制,这使得Flink在面临颠簸状态数据的远程传输问题时,容易出现反复反压的情况,极大地影响了Flink传输数据的效率,故而本文将针对此问题展开研究。

例如 从我的工作经历来说,flink做简单的etl操作 ,接受kafka 数据 插入es中,数据量 大小时大时小时,实际使用来看 spark streaming 性能远远好于flink 就是因为 flink的反压

1.4 flink task与task之间的反压

Flink的反压原理如下图所示,假如Flink的一个Job分为Task A、B、C,其中Task A是Source Task、Task B处理数据、Task C为Sink Task。假如Task C由于各种原因吞吐量降低,会将负载信息反馈给Task B,Task B会降低向Task C发送数据的速率,此时若Task B还保持从Task A读取数据,数据会把Task B的Send Buffer和Receive Buffer撑爆,导致OOM或者丢失数据。所以,当Task B的Send Buffer和Receive Buffer被用完后,Task B会用同样的原理将负载信息反馈给Task A,Task A收到Task B的负载信息后,会降低给Task B发送数据的速率,以此类推。

图1

Flink反压存在Task内与跨Task两种情况,本文已在图1中标注,本文主要是针对Flink跨Task传输进行反压优化,故下文主要对Flink跨Task传输进行介绍:图2展示了Flink网络传输时的数据流向,可以看到Task Manager A给TaskManager B发送数据,Task Manager A做为Producer,Task Manager B做为Consumer。Producer端的Operator实例会产生数据,最后通过网络发送给Consumer端的Operator实例。Producer端Operator实例生产的数据首先缓存到Task Manager内部的Net Work Buffer。Net Work依赖Netty来做通信,Producer端的Netty内部有Channel Outbound Buffer,Consumer端的Netty内部有Channel Inbound Buffer。Netty最终还是要通过Socket发送网络请求,Socket这一层也会有Buffer,Producer端有Send Buffer,Consumer端有Receive Buffer。

故Flink网络传输时的整个反压过程为:首先Producer Operator从自己的上游或者外部数据源读取到数据后,对一条条的数据进行处理,处理完的数据首先输出到Producer Operator对应的Net Work Buffer中。Buffer写满或者超时后,就会触发将Net Work Buffer中的数据拷贝到Producer端Netty的Channel Outbound Buffer,之后又把数据拷贝到Socket的Send Buffer中,这里有一个从用户态拷贝到内核态的过程,最后通过Socket发送网络请求,把Send Buffer中的数据发送到Consumer端的Receive Buffer。数据到达Consumer端后,再依次从Socket的Receive Buffer拷贝到Netty的Channel Inbound Buffer,再拷贝到Consumer Operator的Net Work Buffer,最后Consumer Operator就可以读到数据进行处理了,这就是两个Task Manager之间的数据传输过程。

图2

1.5 netty水位机制作用分析

分析源码可知,Netty水位机制是一种静态的机制,Netty默认其水位线的高度为定值,这使得Flink系统在面临瞬时流量不稳定的场景(即系统的数据流量值在特别高与特别低的值之间不断跳动时)时,会出现下述两种问题:

  1. 水位值较下游可用缓存区数偏低:如图3 (左图)所示,图中以“圆圈”表示数据,以“方框”表示缓存区的大小,下同。假设当上游A点来临的数据量是9 (Flink中以buffer为数据单位,每个buffer大小为32 k,为便于表述,下文块描述),而此时下游B点的可用缓存区是10,N代表代表数据通道(其作用类似于水坝,水位值的大小决定了其单位时间通过的数据量大小),此处设水位值高度为4,则Flink传输本批次的数据需要3个单位时间(上游共9块数据,每个单位时间只能通过4块的数据,需要3个单位的时间来处理这批数据)。而若此时的水位值为9或者10的话,则只需要一个单位时间,Flink便可以处理本批次的数据。

  2. 水位值较下游可用缓存区数偏高:如图3 (右图),假设当上游A点来临的数据量是4,而此时下游B点的可用缓存区为2,水位值高度为4。由于数据量不于水位值高度,Flink会误以为可以在一单位时间内接受这批数据,如图中可以看出,只有2块的缓存区,直接接收了4块的数据量,会直接导致内存溢出(OOM)甚至引起系统阻塞。综上,由于不合理的静态水位线的设置,使得Flink传输数据时间延长,或者出现非正常的阻塞,进而影响整个Flink的数据传输情况。

图3
综上,由于不合理的静态水位线的设置,使得Flink传输数据时间延长,或者出现非正常的阻塞,进而影响整个Flink的数据传输情况。

2 反压优化算法

虽然可以在数据处理前对Netty所默认的两个buffer高度进行参数调整,但这种默认的定值始终是一种静态的机制。这种相对静态的机制使得Flink在面临远程传输问题时,容易出现上文所述的两种问题。本节将针对Flink反压传输所存在的缺点,提出一种基于动态水位值Flink调度优化算法,并给出例子进行说明。Flink-N算法的核心思想是:把Flink中Netty下游可用buffer数Bt实时写入Redis中,根据Redis中前后时刻buffer数(即Bt值)的大小变化,对水位值Wt进行动态调整,算法流程如图4所示,其具体步骤如下:

第一步,设置访问函数,并创建接口,使得Flink启动的同时运行访问函数。其中,访问函数的作用是,每间隔一段时间访问Netty下游缓存区可用buffer (图中B点位置)的数量,并将其记录到Redis中;

第二步,获得下游可用buffer数Bt;

第三步,取0.8倍的B0值的整数部分(向下取整)作为Netty的高水位值,即令W0H = ⌊0.8|B0|⌋;

第四步,将Bt值反馈到Redis中并记录;

第五步,根据Bt值调整水位值Wt,具体方法为:若Bt大于Bt与Bt−1的平均值,则Wt取Bt大于Bt与Bt−1的平均值;反之,当Bt ≤ Bt−1时,则令Wt = Bt。

第六步,重复第二步、第四步与第五步。

本文选择Redis是因为Flink处理时延是ms级别的,而Redis数据读取速度可达110,000次/s,写数据的速度可达81,000次/s,选择Redis相较于其他数据库而言,不会对Flink的时效性产生负增益。

图4
经过实验室测试,发现吞吐量有明显上升
在这里插入图片描述
cpu利用率也是

在这里插入图片描述
以及延时
在这里插入图片描述

3 重点! 但是 可但是 flink1.5以后的反压过程。

经过跟论文比较发现,实际上 flink1.5已经实现了等同于论文中设想的功能并实现。

在 Flink 层面实现反压机制,就是每一次 ResultSubPartition 向 InputChannel 发送消息的时候都会发送一个 backlog size 告诉下游准备发送多少消息,下游就会去计算有多少的 Buffer 去接收消息,算完之后如果有充足的 Buffer 就会返还给上游一个 Credit 告知他可以发送消息(图上两个 ResultSubPartition 和 InputChannel 之间是虚线是因为最终还是要通过 Netty 和 Socket 去通信)
图2

  • 1.5之前是tcp反压 链路太长 ,会涉及多个task 如果在同一个taskmanager会造成重复使用Socket 阻塞
  • 新的网路栈:TaskManager 传输数据时,不同的 TaskManager 上的两个 Subtask 间通 常根据 key 的数量有多个 Channel,这些 Channel 会复用同一个 TaskManager 级别的 TCP 链接,并且共享接收端 Subtask 级别的 Buffer Pool。
  • 在接收端,每个 Channel 在初始阶段会被分配固定数量的 Exclusive Buffer, 这些 Buffer 会被用于存储接受到的数据,交给 Operator 使用后再次被释放。 Channel 接收端空闲的 Buffer 数量称为 Credit,Credit 会被定时同步给发送端被后 者用于决定发送多少个 Buffer 的数据。
  • 在流量较大时,Channel 的 Exclusive Buffer 可能会被写满,此时 Flink 会向 Buffer Pool 申请剩余的 Floating Buffer。这些 Floating Buffer 属于备用 Buffer,哪 个 Channel 需要就去哪里。而在 Channel 发送端,一个 Subtask 所有的 Channel 会共享同一个 Buffer Pool,这边就没有区分 Exclusive Buffer 和 Floating Buffer。

看图可以知道 ,底层的通信肯定是socket,但实际用的组件是netty。是netty在互相通信,来实现反压信息的传递

在这里插入图片描述

4 flink反压问题的查找瓶颈办法

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

一般情况使用Metrics都能够定位到问题,是cpu 内存,然后再定位算子,查看设计是否有缺陷,定位节点,加Metrics
我们在监控反压时会用到的 Metrics 主要和 Channel 接受端的 Buffer 使用率有关,最为有用的是以下几个:
Metrics: Metris描述
outPoolUsage发送端 Buffer 的使用率
inPoolUsage接收端 Buffer 的使用率
floatingBuffersUsage(1.9 以上)接收端 Floating Buffer 的使用率
exclusiveBuffersUsage (1.9 以上)接收端 Exclusive Buffer 的使用率

Netty | 设置高低水位线避免 OOM Netty 中的高低水位线是什么? Netty 中的 Channel 都有一个写缓冲区; 这个写缓冲区是 ChannelOutboundBuffer,这是个 Netty 发数据时的仓库,要发送的数据以数据结构 Entry 的形式存在仓库中,Entry 是个链表中的节点; Netty 中的高低水位线,对应的就是这个链表中节点的数量范围,用于限制程序的写操作,自己在写程序的时候,需要... 阅读详情

相关推荐

Netty 在项目开发中的一些实践

文章目录性能篇网络参数优化SO_SNDBUF/SO_RCVBUFTCP_NODELAYSO_BACKLOGSO_KEEPALIVE业务线程池的必要性共享 ChannelHandler设置高低水位线GC 参数优化堆内存堆外内存年轻代内存池 & 对象池Native 支持线程绑定高可用篇连接空闲检测 + 心跳检测解码器保护线程池隔离流量整形堆外内存泄漏排查思路堆外内存回收堆外内存代码监控Netty 自带检测工具MemoryAnalyzer 内存分析Btrace 神器二分排查法:笨方法解决大问题总结 这是专

712

Netty流量控制之一:高低水位

当Channel write向缓冲区写入数据的时候,如果数据量超过了设置的高水位值,就设置通道Channel不可写状态。 当Channel flush将缓冲区中的数据写入到TCP缓冲区之后,如果Netty缓冲区的数据量低于低水位值时,就设置通过Channel可写状态。 Netty默认设置的高水位为64KB,低水位为32KB。 1. 例子 ServerBootstrap sb = new ServerBootstrap(); bootstrap.childOption(ChannelOption.WRITE_

MiniLuLu的博客 3218

【信息科学与工程学】【数据中心】第三十二篇 云数据中心的计算/存储/网络的核心挑战01

状态方程: SOCk+1​=SOCk​−Qn​ik​Δt​;: 三相电流变换到αβ坐标系: iα​=32​​(ia​−21​ib​−21​ic​), iβ​=32​​(23​​ib​−23​​ic​). 计算瞬时有功功率p和无功功率q,经低通滤波器分离直流分量,反变换得基波电流,差值即为谐波指令。: 节点i的信念 bi​(xi​)=ϕi​(xi​)∏j∈N(i)​mji​(xi​), 消息 mij​(xj​)=∑xi​​ϕi​(xi​)ψij​(xi​,xj​)∏k∈N(i)\j​mki​(xi​).

weixin_49199313的博客 221

Netty源码系列 之 AbstractUnsafe & 高低水位线 & ChannelOutboundBuffer 源码

Netty源码系列 之 AbstractUnsafe & 高低水位线 & ChannelOutboundBuffer 源码

Eriksen的博客 1172

【信息科学与工程学】计算机科学与自动化——第八十四篇 C++分布式软件高并发/高可用算法01

4. 提交:协调者选择提交时间戳(>所有读时间戳),两阶段提交:a) 写意图预提交到所有参与者,b) 参与者持久化后确认,c) 协调者决定提交,异步清理意图。:客户端请求发送到协调节点,协调节点根据路由转发到主分片所在节点。Span有父子关系。1. 索引文档:客户端发送PUT请求到协调节点,协调节点路由到主分片节点,主分片写入本地,然后并行复制到副本分片,等待确认后响应客户端。3. 搜索:客户端发送搜索请求到协调节点,协调节点广播到所有相关分片,每个分片执行查询,返回结果,协调节点合并、排序、分页后返回。

weixin_49199313的博客 1081

NY8A053E 例程 之 PWM Ouput

更多关于NY8A053E的相关例程请留言!

倪彬笑阳的博客 2925

Netty的高低水位控制读写

https://zhuanlan.zhihu.com/p/272840446

YangangwuWuyangang的专栏 570

在abaqus中利用point-based 来快捷定义螺栓连接

abaqus中可以通过point-based方式定义连接点的位置,并对连接方式进行定义,可以进行螺栓连接的模拟。 可以通过逐点输入坐标或导入外部的坐标位置 也可以通过阵列的方式定义点 定义完点后就利用create fasteners,选择point-based,选取刚才创建好的点阵列,然后定义连接的属性,如下图 定义connector section时,类型选择translator,相当于只有1方向可以动,定义弹性模量以及破坏准则。 案例操作 假如有两个板,通过...

fiber_tape的博客 7350

【原理|数据传输】Flink系列之数据传输原理

先通过一个job了解一下数据传输的流程,再拓展到跨TaskManager,之后讨论taskmanager之间使用netty进行数据传输的相关细节

hiliang521的博客 1437

surfer10与Arcgis10.3 完美生成等值线和等值面方法

surfer10 与Arcgis10.3生成等值线和等值面的步骤如下: 1.准备surfer用的Book1.dat文件,格式如下: "x" "y" "z" 116.471992 40.809975 232 116.335556 40.700542 1235 116.541626 40.713333 214 116.73349 40.798607 566 2.在surfer中,选择Gr

哈里·雪利博客 1万+

CNN+LSTM+Attention+DNN模型实战:pytorch搭建CNN+LSTM+Attention+DNN行车速度预测

CNN+LSTM+Attention+DNN模型实战:pytorch搭建CNN+LSTM+Attention+DNN行车速度预测

6045

netty 水位线与oom

Netty版本4.1.6。 当channel被调用到writAndFlush()的时候,如同字面意思,实现了两次操作,write和flush,其中write的时候并没有将消息直接写入到socket中,而是封装为ChannelOutboundBuffer中的等待发送消息链表中的一个节点,只有等到flush操作发生的时候才会将链表中的消息全都写入到socket中。这样做的目的可以通过缓存消息的方式,减少flush到的套接字缓冲区的次数。因此,当write写入消息过快,而没来得及进行flush的时候将会导致链表

不说话装高手 1042

【RTD】AD7793驱动程序

AD7793完整驱动程序,支持两线、三线、四线RTD。

只要思想不滑坡,想法总比问题多。 6179

Netty中控制IO运行比例占比-分析

       cancelledKeys = 0;                needsToSelectAgain = false;                final int ioRatio = this.ioRatio;                if (ioRatio == 100) {                    try {                     ...

每天进步一点点的专栏 2219

leetcode134 加油站

题目如下 在一条环路上有 N 个加油站,其中第 i 个加油站有汽油 gas[i] 升。 你有一辆油箱容量无限的的汽车,从第 i 个加油站开往第 i+1 个加油站需要消耗汽油 cost[i] 升。你从其中的一个加油站出发,开始时油箱为空。 如果你可以绕环路行驶一周,则返回出发时加油站的编号,否则返回 -1。 说明: 如果题目有解,该答案即为唯一答案。 输入数组均为非空数组,且长度相同。 输...

ayang818 's blog 234

基于Spring Security 6的OAuth2 系列之二 - 客户端--非代码演示授权码模式

至此,我们就使用浏览器+postman工具演示了通过授权码模式去获取Gitee的用户信息。这过程中,我们只是遵循OAuth2的流程,就能够实现授权方法。那么接下来,我们采用代码方式来实现这个流程。

代码让AI扣 1813

Netty 中的流控与统计

转自:https://emacsist.github.io/2018/04/26/netty-中的流控与统计/Netty 流量相关的包io.netty.handler.trafficChannelTrafficShapingHandler : Channel 级别的GlobalChannelTrafficShapingHandler : 全局级别的(无论打开多少Channel) 以及 每条 Cha...

infi 7212

一个 ABAP 工具,能打印系统里某个用户对 BSP 应用的浏览历史记录

只要一个用户在 SAP ABAP 系统里浏览过 BSP 页面,会留下浏览历史记录。本工具会解析出这些记录,打印出该用户浏览的历史事件,和浏览过的页面名称。

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 548

在Netty底层监控消息发送到Socket的时间

1、调用writeAndFlush方法之后获取ChannelFuture; 2、新增消息发送ChannelFutureListener,监听消息发送结果,如果消息写入网络Socket成功,则Netty会回调ChannelFutureListener的operationComplete方法; 3、在消息发送ChannelFutureListener的operationComplete方法中进行性

流子的专栏 8663

IDEA的使用指南

IDEA基于java的使用手册,可以最快速的上手,在使用中不断的丰富自己的使用技巧.

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

基于 Netty 的帧调度策略,自行实现流量控制及可靠性通信

Java 服务器和硬件设备通信的过程中,众多的硬件设备可能数据帧处理能力较差,可靠性较差,所以在 Netty 模块中使用了帧调度算法。服务器大规模下发数据帧时,可进行有效的拥塞控制、超时重发,可有效提升集群设备的可靠性,降低集群设备的研发难度。

雪中亮 4300

RU DOS版、EFI版32bit/64bit BIOS常用工具

DOS版、EFI版的RU工具,可用来查看IO、MEM、PCI、SMBIOS等资源。亲测在EFI SHELL下可用。

Netty4 读写水位控制分析

服务器上看看默认是多少 Configure high and low write watermarks Set sane WRITE_BUFFER_HIGH_WATER_MARK andWRITE_BUFFER_LOW_WATER_MARK ServerBootstrap bootstrap = new ServerBootstrap(); bootstrap.childO

流子的专栏 1万+

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

Netty设置高低水位

Configure high and low write watermarks Server ServerBootstrap bootstrap = new ServerBootstrap(); bootstrap.childOption(ChannelOption.WRITE_BUFFER_HIGH_WATER_MARK, 32 * 1024); bootstrap.chi...

weixin_34281537的博客 1254

Netty 水位详解

Netty 写水位 在启动Netty bootstrap的时候可以设置ChannelOption选项,其中ChannelOption中有一项WRITE_BUFFER_HIGH_WATER_MARK选项和WRITE_BUFFER_LOW_WATER_MARK选项,,此配置写缓冲区(OutbounduBuffer)相关,此配置可以帮助用户监控当前写缓冲区的水位状况,ChannelOutboundBu...

feiying的博客 8299

Day2 - Flink DataStream API 与转换算子:从 Source 到 Sink

实现或@Override// 发射数据@Override// 使用用自定义逻辑聚合,比 sum/min/max 更灵活。// 求每个用户的总消费金额reduce 的输入和输出类型必须相同。Flink 会把满足条件的相邻算子合并成一个 Task,在同一个线程里执行,减少线程切换和网络开销。合并条件上下游并行度相同;分区策略是 Forward;没有被用户手动断开。

YEEMOLY的博客 209

Apache Flink 零基础

低代码、易开发、易维护、可读性强,适配实时数仓分层、指标统计、数据清洗、多源数据关联等绝大多数业务场景,支持Kafka、Doris、MySQL、Hive等主流组件读写,是企业实时开发主流方案。:接收客户端提交的实时/离线任务、解析任务逻辑、生成DAG执行流程图、分配集群资源、调度任务运行、管理Checkpoint/Savepoint、处理任务故障重启、协调集群节点状态。手动触发的状态快照,主要用于任务升级、代码迭代、版本更新、集群迁移、任务重启等运维操作,保证业务无感知、数据不错乱、任务无缝恢复。

2402_85354210的博客 351
上一篇: flink cdc原理与使用
下一篇: flink sql 实战实例 及延伸问题:聚合/数据倾斜/DAU/Hive流批一体 等
Direction_Wind
博客等级 码龄8年 6438粉丝 102原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Direction_Wind

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值