前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >Flink流量控制与反压机制完全总结

Flink流量控制与反压机制完全总结

作者头像
小晨说数据
发布于 2022-03-10 02:42:02
发布于 2022-03-10 02:42:02
7700
举报
文章被收录于专栏:小晨讲Flink小晨讲Flink

▍前沿

笔者最近回顾自己对Flink技术栈细节的理解,发现对Flink的网络栈、流控与反压这一套机制存在比较大的盲区。虽然平时多次处理过作业反压的问题,但是不完全理解背后的实现显然说不过去。于是专门写一篇总结,站在大佬们的肩膀上彻底搞清楚Flink是怎么做流控与处理反压的。

▍Flink网络传输的数据流向

Flink网络传输的数据流向如下图所示。

Sender在发送数据时,首先写入TaskManager内部的网络缓存,利用Netty进行传输——将待发送的数据存入Netty的ChannelOutboundBuffer,再经由Socket的发送缓存发送出去。Receiver在接收数据时是反过来的,同样要经过3层缓存,即Socket接收缓存→Netty ChannelInboundBuffer→TaskManager网络缓存。要实现流量控制,就是在上面的流程上做文章。

▍Flink的反压传播

反压(back pressure)就是流式系统中关于处理能力的动态反馈机制,并且是从下游到上游的反馈。下图示出数据流在Flink TaskManager之间流动的逻辑。

可见,一旦因为下游处理能力不足而出现反压,反压信号的传播应该分为两个阶段:一是从下游TaskManager的输入端(InputGate)传播到直接上游TaskManager的输出端(ResultPartition);二是在TaskManager内部从输出端传播到输入端。当然,我们要重点考虑的是跨TaskManager的反压传播,因为它的链路比较长(参考上一节的数据流向图),更有可能成为瓶颈。

下面先来介绍旧版本中的流控和反压机制。

▍Flink 1.5之前:基于TCP的流控和反压

在1.5版本之前,Flink并没有特别地去实现自己的流控机制,而是在传输层直接依靠TCP协议自身具备的滑动窗口机制(大学计算机网络课程必讲)。下面通过实例来复习TCP滑动窗口是如何实现流控的。

  1. 初始情况如下图所示。Sender每单位时间发送3个包,发送窗口初始大小为3;Receiver每单位时间接收1个包,接收窗口初始大小为5(与接收缓存的大小相同)。
  1. Sender发送1~3三个包,Receiver接收到之后将它们放入缓存。
  1. Receiver消费一个包,接收窗口向前滑动一格,并告知Sender ACK=4(表示可以从第4个包开始发送),以及Window=3(表示接收窗口当前的空余量为3)。
  1. Sender接收到ACK消息后发送4~6三个包,Receiver接收到之后将它们放入缓存。
  1. Receiver消费一个包,接收窗口向前滑动一格,并告知Sender ACK=7(表示可以从第7个包开始发送),以及Window=1(表示接收窗口当前的空余量为1)。Sender接收到ACK消息之后,发现Receiver只能再接收1个包了,就将发送窗口的大小调整为1并发送包7,达到了限流的目的。

接着这个流程分析下去,可以得知Sender最终会无法发送数据(因为Receiver报告Window=0),直到Receiver消费掉缓存中的数据才能继续发送。同时Sender还会定时向Receiver发送ZeroWindowProbe探测消息,保证Receiver能够及时将消费能力报告给Sender。

接下来用实例介绍反压流程。

  1. 如图所示,Sender发送速度与Receiver接收速度的比是2:1,起初是可以正常发送与接收的。
  1. 一段时间过后,Receiver端InputChannel本身的缓存被耗尽,因此会向本地缓存池LocalBufferPool申请新的缓存。
  1. 一段时间过后,LocalBufferPool的可用额度会被耗尽,因此会向网络缓存池NetworkBufferPool申请新的缓存。
  1. 随着数据不断积压,NetworkBufferPool的额度也会被耗尽,此时没有空间再接收新的数据,Netty的auto read会被关闭,不再从Socket缓存读取数据。
  1. Socket缓存耗尽后,Receiver报告Window=0(参见上文的滑动窗口),Sender的Socket就会停止发送数据。
  1. Sender端的Socket缓存积压,导致Netty无法再发送数据。
  1. 待发送的数据都积压在Sender的ChannelOutboundBuffer中,当数据量超过Netty的high watermark之后,Channel被置为不可写,ResultSubPartition也就不再向Netty写数据。
  1. Sender端的ResultSubPartition缓存满了之后,就会像Receiver端的InputChannel一样,不断地向LocalBufferPool和NetworkBufferPool申请新的缓存,直到缓存全部耗尽,RecordWriter不能再写数据。

这样,我们就实现了反压向上游TaskManager的传递。

▍Flink 1.5之后:基于Credit的流控和反压

基于TCP的流控和反压方案有两大缺点:

  • 只要TaskManager执行的一个Task触发反压,该TaskManager与上游TaskManager的Socket就不能再传输数据,从而影响到所有其他正常的Task,以及Checkpoint Barrier的流动,可能造成作业雪崩;
  • 反压的传播链路太长,且需要耗尽所有网络缓存之后才能有效触发,延迟比较大。

Flink 1.5+版本为了解决这两个问题,引入了基于Credit的流控和反压机制。它本质上是将TCP的流控机制从传输层提升到了应用层——即ResultPartition和InputGate的层级,从而避免在传输层造成阻塞。具体来讲:

  • Sender端的ResultSubPartition会统计累积的消息量(以缓存个数计),以backlog size的形式通知到Receiver端的InputChannel;
  • Receiver端InputChannel会计算有多少空间能够接收消息(同样以缓存个数计),以credit的形式通知到Sender端的ResultSubPartition。

也就是说,Sender和Receiver通过互相告知对方自己的处理能力的方式来精准地进行流控(注意backlog size和credit也是要通过传输层的,不是直接交换的)。接下来仍然通过实例来说明基于Credit的流控和反压流程。

  1. 仍然是Sender发送速度与Receiver接收速度的比是2:1的情景。Sender端的ResultSubPartition积压了2个缓存的数据,因此会将该批次要发送的数据与backlog size = 2一同发往Receiver。 Receiver收到当前批数据和backlog size之后,会计算InputChannel是否有足够的缓存来接收下一批数据,如果不够,则会去LocalBufferPool/NetworkBufferPool申请缓存,并将credit = 3通知到上游的ResultSubPartition,表示自己能够接收3个缓存的消息。
  1. 随着Receiver端的数据不断积压,网络缓存最终被耗尽,因此会反馈给上游credit = 0(相当于TCP滑动窗口中的window = 0),Sender端ResultPartition到Netty的链路会被阻断。按照上一节所述的流程,Sender端的网络缓存会被更快地耗尽,RecordWriter不能再写数据,从而达到反压的效果。

由上可知,反压信号在TaskManager之间不需要再通过传输层随着数据向上反馈,大大降低了反压的延迟。并且也不会因为一个Task反压而阻塞整个Socket链路,能够相当精确地在Task粒度控制流量,不仅轻量级,而且高效。

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

本文分享自 小晨说数据 微信公众号,前往查看

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

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

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
Flink 重点原理与机制 : 网络流控及反压机制
首先我们可以看下这张最精简的网络流控的图,Producer 的吞吐率是 2MB/s,Consumer 是 1MB/s,这个时候我们就会发现在网络通信的时候我们的 Producer 的速度是比 Consumer 要快的,有 1MB/s 的这样的速度差,假定我们两端都有一个 Buffer,Producer 端有一个发送用的 Send Buffer,Consumer 端有一个接收用的 Receive Buffer,在网络端的吞吐率是 2MB/s,过了 5s 后我们的 Receive Buffer 可能就撑不住了,这时候会面临两种情况:
大数据老哥
2021/09/16
2.3K0
Flink 重点原理与机制 : 网络流控及反压机制
Flink反压原理深入浅出及解决思路
Apache Flink 是一个分布式大数据处理引擎,可对有限数据流和无限数据流进行有状态或无状态的计算,能够部署在各种集群环境,对各种规模大小的数据进行快速计算。既然是对流式数据进行处理,那么就要面临数据在流动计算时,上下游数据通信以及数据处理速度不一致所带来的问题。 本文先从「生产者-消费者模式」的角度介绍了Flink中的数据传输,从而引出了「反压」的概念。接着介绍了Flink在V1.5前「基于TCP的反压机制」以及V1.5后「基于Credit的反压机制」分别如何实现网络流控。最后针对一个反压案例进行分析,介绍了如何进行反压定位和资源调优,并展示了调优结果。 希望在阅读完本文后,读者可以深入理解Flink节点反压的概念以及背后的原理,在遇到反压场景时,能够快速定位瓶颈点,并拥有一套基本的调优思路。
出其东门
2022/12/05
2.2K0
Flink反压原理深入浅出及解决思路
Flink的处理背压​原理及问题-面试必备
反压机制(BackPressure)被广泛应用到实时流处理系统中,流处理系统需要能优雅地处理反压(backpressure)问题。反压通常产生于这样的场景:短时负载高峰导致系统接收数据的速率远高于它处理数据的速率。许多日常问题都会导致反压,例如,垃圾回收停顿可能会导致流入的数据快速堆积,或者遇到大促或秒杀活动导致流量陡增。反压如果不能得到正确的处理,可能会导致资源耗尽甚至系统崩溃。反压机制就是指系统能够自己检测到被阻塞的Operator,然后系统自适应地降低源头或者上游的发送速率。目前主流的流处理系统 Apache Storm、JStorm、Spark Streaming、S4、Apache Flink、Twitter Heron都采用反压机制解决这个问题,不过他们的实现各自不同。
Spark学习技巧
2020/09/08
5.3K0
Flink的处理背压​原理及问题-面试必备
Flink完美的反压机制
整体上来说的话,Flink 内部是基于 producer-consumer 模型来进行消息传递的,也正是 producer-consumer 模型的存在,Flink 能够实现完美的反压。要想更好的理解为什么 Flink 可以完美的实现反压,我们首先需要明白 Flink内部的 producer-consumer 模型,理解了模型,自然也就懂了反压。 我会用几张图来展示 Flink的 producer-consumer 模型。 我们以 WC 为例,这里盗用一下别人的图片,感谢,笔芯!
shengjk1
2019/08/29
1.5K0
Flink完美的反压机制
关于 Flink 状态与容错机制
Flink 作为新一代基于事件流的、真正意义上的流批一体的大数据处理引擎,正在逐渐得到广大开发者们的青睐。就从我自身的视角看,最近也是在数据团队把一些原本由 Flume、SparkStreaming、Storm 编写的流式作业往 Flink 迁移,它们之间的优劣对比本篇暂不讨论。
Single
2022/09/08
7090
关于 Flink 状态与容错机制
批流统一计算引擎的动力源泉—Flink Shuffle机制的重构与优化
本文讲述的shuffle概念范围如下图虚线框所示,从上游算子产出数据到下游算子消费数据的全部流程,基本可以划分成三个子模块:
王知无-import_bigdata
2019/06/02
4.4K0
Flink重点难点:Flink任务综合调优(Checkpoint/反压/内存)
我们在Flink重点难点:状态(Checkpoint和Savepoint)容错与两阶段提交一文中对Flink的Checkpoint做过详细的介绍。
大数据真好玩
2021/11/23
7.2K0
Flink重点难点:Flink任务综合调优(Checkpoint/反压/内存)
Flink源码解读系列 | Flink中接收端反压以及Credit机制
可以看到每个task都会有自己对应的IG(inputgate)对接上游发送过来的数据和RS(resultPatation)对接往下游发送数据, 整个反压机制通过inputgate,resultPatation公用一个一定大小的memorySegmentPool来实现(Flink中memorySegment作为内存使用的抽象,类比bytebuffer), 公用一个pool当接收上游数据时Decoder,往下游发送数据时Encoder,都会向pool中请求内存memorySegment 。因为是公共pool,也就是说运行时,当接受的数据占用的内存多了,往下游发送的数据就少了,这样是个什么样的情况呢?
大数据真好玩
2020/09/22
9360
Flink源码解读系列 | Flink中接收端反压以及Credit机制
Flink源码解读系列 | Flink中发送端反压以及Credit机制
上一篇《Flink接收端反压机制》说到因为Flink每个Task的接收端和发送端是共享一个bufferPool的,形成了天然的反压机制,当Task接收数据的时候,接收端会根据积压的数据量以及可用的buffer数量(可用的memorySegment数)来决定是否向上游发送Credit(简而言之就是当我还有空间的时候,我向上游也就是上一个Task的发送端发送一个ack消息,表明我还有空间你可以发送数据过来,如果下游没有给你Credit就证明下游已经堵了,没有空间了也就不能继续往下游发送了)
大数据真好玩
2020/09/22
1.1K0
Flink源码解读系列 | Flink中发送端反压以及Credit机制
Flink中的数据抽象&交换&Credit&背压问题详解
其中,第一个构造函数的checkBufferAndGetAddress()方法能够得到direct buffer的内存地址,因此可以操作堆外内存。
王知无-import_bigdata
2023/04/07
8250
Flink中的数据抽象&交换&Credit&背压问题详解
Flink企业级优化全面总结(3万字长文,15张图)
Flink性能调优的第一步,就是为任务分配合适的资源,在一定范围内,增加资源的分配与性能的提升是成正比的,实现了最优的资源配置后,在此基础上再考虑进行后面论述的性能调优策略。
大数据老哥
2021/11/04
4.5K0
面试被问到Flink的checkpoint问题,给问懵逼了....
Checkpoint 机制
木野归郎
2020/07/02
1.1K0
面试被问到Flink的checkpoint问题,给问懵逼了....
Flink作业反压处理
反压(backpressure)是实时计算应用开发中,特别是流式计算中,十分常见的问题。反压意味着数据管道中某个节点成为 瓶颈,处理速率跟不上上游发送数据的速率,而需要对上游进行限速。由于实时计算应用通常使用消息队列来进行生产端和 消费端的解耦,消费端数据源是 pull-based 的,所以反压通常是从某个节点传导至数据源并降低数据源(比如 Kafka consumer)的摄入速率。
zeekling
2023/01/08
1.3K0
Flink作业反压处理
Flink原理 | Flink中的数据抽象及数据交换过程
场景描述:Flink作为一个高效的流框架,为了避免JVM的固有缺陷(java对象存储密度低,FGC影响吞吐和响应等),必然走上自主管理内存的道路。
王知无-import_bigdata
2019/12/05
2.2K1
Flink原理 | Flink中的数据抽象及数据交换过程
阿里二面:Flink内存管理是如何实现的?
从大的方面来说,TaskManager进程的内存模型分为JVM本身所使用的内存和Flink使用的内存,Flink使用了堆上内存和堆外内存。
857技术社区
2022/05/17
5740
阿里二面:Flink内存管理是如何实现的?
flink部分面试题汇总
当 Flink 集群启动后,⾸先会启动⼀个 JobManger 和⼀个或多个的 TaskManager。由 Client 提交任务给 JobManager,JobManager 再调度任务到各个 TaskManager 去执⾏,然后 TaskManager 将⼼跳和统计信息汇报给 JobManager。TaskManager 之间以流的形式进⾏数据的传输。上述三者均为独⽴的 JVM 进程。
从大数据到人工智能
2022/03/12
1.4K0
flink部分面试题汇总
Flink重点难点:内存模型与内存结构
Java 虚拟机在执行Java程序的过程中会把它在主存中管理的内存部分划分成多个区域,每个区域存放不同类型的数据。下图所示为java虚拟机运行的时候,主要的内存分区:
王知无-import_bigdata
2021/09/22
1.5K0
【Flink】第八篇:Flink 内存管理
(以Flink 1.10为蓝本,Flink 1.10对之前的Flink版本的内存模型做了大量优化)
章鱼carl
2022/03/31
2.6K0
【Flink】第八篇:Flink 内存管理
Flink 网络传输优化技术
作为工业级的流计算框架,Flink 被设计为可以每天处理 TB 甚至 PB 级别的数据,所以如何高吞吐低延迟并且可靠地在算子间传输数据是一个非常重要的课题。此外,Flink 的数据传输还需要支持框架本身的特性,例如反压和用于测量延迟的 latency marker。在社区不断的迭代中,Flink 逐渐积累了一套值得研究的网络栈(Network Stack),本文将详细介绍 Flink Network Stack 的实现细节以及关键的优化技术。
王知无-import_bigdata
2019/08/13
2.1K0
Flink性能调优小小总结
Flink是依赖内存计算,计算过程中内存不够对Flink的执行效率影响很大。可以通过监控GC(Garbage Collection),评估内存使用及剩余情况来判断内存是否变成性能瓶颈,并根据情况优化。
王知无-import_bigdata
2021/04/21
5.4K0
Flink性能调优小小总结
推荐阅读
相关推荐
Flink 重点原理与机制 : 网络流控及反压机制
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档