Flink中接收端反压以及Credit机制 (源码分析)
先上一张图整体了解Flink中的反压
可以看到每个task都会有自己对应的IG(inputgate)对接上游发送过来的数据和RS(resultPatation)对接往下游发送数据,
整个反压机制通过inputgate,resultPatation公用一个一定大小的memorySegmentPool来实现(Flink 中memorySegment作为内存使用的抽象,类比bytebuffer),
公用一个pool当接收上游数据时Decoder,往下游发送数据时Encoder,都会向pool中请求内存memorySegment
因为是公共pool,也就是说运行时,当接受的数据占用的内存多了,往下游发送的数据就少了,这样是个什么样的情况呢?
比如说你sink端堵塞了,背压了写不进去,那这个task的resultPatation无法发送数据了,也就无法释放memorySegment了,相应的用于接收数据的memorySegment就会越来越少
直到接收数据端拿不到memorySegment了,也就无法接收上游数据了,既然这个task无法接收数据了,自然引起这个task的上一个task数据发送端无法发送,那上一个task又反压了
所以这个反压从发生反压的地方,依次的往上游扩散直到source,这个就是flink的天然反压。
从源码来看一下flink是如何实现的
来到数据接收的地方StreamInputProcessor.java中processInput()方法中
这里通过通过handler的getNextNonBlocked()方法获取到了bufferOrEvent后面就会将这个bufferOrEvent解析成record数据然后使用用户的代码处理了
其实这里的handler分为两种
- BarrierBuffer
- BarrierTracker
区别主要是barrierbuffer实现了barrier对齐的数据缓存,用于实现一次语义,这里以后随缘更新到容错机制的时候讲
来看一下getNextNonBlocked()方法
这个看到了通过会通过上游inputGate获取数据,具体看一下getNextBufferOrEvent()其中有两个比较重要的调用
先看requestPartitions()
先遍历了所有的inputchannel然后调用了requestSubpartition()在其中
先看一下1处,这里返回了一个Netty的Client来看一下createPartitionRequestClient是怎么创建的
可以看到源码的描述,这里其实就是创建与上游发送数据端的tcp连接的client端,用来接收上游数据的
接着
这里如果已经建立TCP连接就直接拿,与上游还没有建立tcp连接的话就会先初始化Client端,通过这个connect()方法
来看一下第一次是如何初始化连接的
看到这个应该熟悉Netty的同学一眼就了解了,在1处就是Client的具体逻辑了,然后与上游端口建立连接
来看一下具体的Client端具体的逻辑,这里最好对netty有一定的认识
- 1处是一个用于Encoder 的ChannelOutboundHandler常规的编码器没有什么好说的
2处是用于Decoder的ChannelinboundHandler常规的解码器没有什么好说的
- 3处 这里分为两种Handler,区别主要是在notifyCreditAvailable()方法
PartitionRequestClientHandler: 不带信任机制的
CreditBasedPartitionRequestClientHandler:带credit信任机制的
这里取出了所有的带有信任的上游inputChannel并且向其响应发送了一个Credit对象
那带Credit机制的handler何时触发userEventTriggered()来触发向上游发送Credit呢?
先不慌,先来看下client接收到数据后做了什么,看下Nettyclient端的channelRead()方法(这里只看credit机制的)
decodeMsg()方法中
decodeBufferOrEvent()方法
在没有Credit机制的PartitionRequestClientHandler中
requestBuffer()方法就是请求memorySegmentPool中的memorySegment
这里不能确保能获取到,所以会用一个while(true)一直挂着
在Credit机制的CreditBasedPartitionRequestClientHandler中
请求requestBuffer()方法就是请求memorySegmentPool中的memorySegment因为信任机制在请求前就已经保证有足够的memorySegment所以不会请求不到,这里请求不到直接就抛异常了
然后OnBuffer( )方法
1处将将这个buffer加入到了这个receivedBuffers的ArrayDeque中,这里要注意receivedBuffers,这个queue后面会用到(后面处理数据就是循环的从这个queue中poll拉数据出来)
这里还要注意onBuffer方法还传入了backlog参数,这里是一个积压的数据量
接着会根据积压的数据量
当可用的buffer数 <(挤压的数据量 + 已经分配给信任Credit的buffer量) 时,就会向Pool中继续请求buffer,这里请求不到也会一直while形成柱塞反压
然后通过notifyCreditAvailable()方法发送Credit,具体来看一下
可用看到这里就触发了前面说到的向上游发送Credit的方法了
到这里,Nettyclient端的初始化以及Netty的处理逻辑就讲完了
现在回到最最开始的地方
requestPartition()那里创建nettyclient后
currentChannel.getNextBuffer()方法中
前面我们说到的NettyClient端channelRead读取数据后会把数据放到一个recivedBuffers的queue中,这里就是去那个queue中取数据然后返回到我们的
数据接收的地方StreamInputProcessor.java中processInput()方法中的得到上游数据以后,就是开始执行我们用户的代码了调用processElement方法了,
然后while(true)开始了下一轮拉取数据然后处理的过程
Flink中接收端反压以及Credit机制 (源码分析)的更多相关文章
- Flink中发送端反压以及Credit机制(源码分析)
上一篇<Flink接收端反压机制>说到因为Flink每个Task的接收端和发送端是共享一个bufferPool的,形成了天然的反压机制,当Task接收数据的时候,接收端会根据积压的数据量以 ...
- Flink中TaskManager端执行用户逻辑过程(源码分析)
TaskManager接收到来自JobManager的jobGraph转换得到的TDD对象,启动了任务,在StreamInputProcessor类的processInput()方法中 通过一个whi ...
- Springboot学习04-默认错误页面加载机制源码分析
Springboot学习04-默认错误页面加载机制源码分析 前沿 希望通过本文的学习,对错误页面的加载机制有这更神的理解 正文 1-Springboot错误页面展示 2-Springboot默认错误处 ...
- ApplicationEvent事件机制源码分析
<spring扩展点之三:Spring 的监听事件 ApplicationListener 和 ApplicationEvent 用法,在spring启动后做些事情> <服务网关zu ...
- Android事件分发机制源码分析
Android事件分发机制源码分析 Android事件分发机制源码分析 Part1事件来源以及传递顺序 Activity分发事件源码 PhoneWindow分发事件源码 小结 Part2ViewGro ...
- Flink中Idle停滞流机制(源码分析)
前几天在社区群上,有人问了一个问题 既然上游最小水印会决定窗口触发,那如果我上游其中一条流突然没有了数据,我的窗口还会继续触发吗? 看到这个问题,我蒙了???? 对哈,因为我是选择上游所有流中水印最小 ...
- 时间轮机制在Redisson分布式锁中的实际应用以及时间轮源码分析
本篇文章主要基于Redisson中实现的分布式锁机制继续进行展开,分析Redisson中的时间轮机制. 在前面分析的Redisson的分布式锁实现中,有一个Watch Dog机制来对锁键进行续约,代码 ...
- Servlet容器Tomcat中web.xml中url-pattern的配置详解[附带源码分析]
目录 前言 现象 源码分析 实战例子 总结 参考资料 前言 今天研究了一下tomcat上web.xml配置文件中url-pattern的问题. 这个问题其实毕业前就困扰着我,当时忙于找工作. 找到工作 ...
- 【Cocos2d-x 3.x】 事件处理机制源码分析
在游戏中,触摸是最基本的,必不可少的.Cocos2d-x 3.x中定义了一系列事件,同时也定义了负责监听这些事件的监听器,另外,cocos定义了事件分发类,用来将事件派发出去以便可以实现相应的事件. ...
随机推荐
- 2017CCSP-01 五子棋 简单模拟
题面和数据 对于每个空格,先定义一个变量cnt=0,表示空格填充后对五子数量的变化,四个方向进行两边搜索,设对于每个方向连续的白棋子分别为\(wa\),\(wb\),有以下几种情况. \(wa> ...
- 【福利】离散&C++&硬件一笔记合集
离散 C++ 硬件
- _self.$scopedSlots.default is not a function报错
问题: 当同一页面有elementUI的多个table表格时,如果用到v-if来动态展示表格,切换时出现如下报错: 原因: 是因为表格是element-ui通过循环产生的,而vue在dom重新渲染时有 ...
- mui中判断是点击还是滑动
判断和滑动是两种触发方式 滑动分为四种,上下左右(swipeup,swipedown,swipeleft,swiperight) 点击分为两种,点击和双击,一般用单机(tap) 根据自己不同的需求进行 ...
- Nginx常用命令,解决你日常运维的烦恼
前面,跟大家简单地介绍了负载均衡和Nginx的一些基础配置(Nginx负载均衡配置实例),接下来,跟大家介绍一下Nginx的常用命令,便于日常的运维. 查看原文 停止Nginx的方法 通过之前的学习, ...
- cocos2d-x Windows 环境搭建
本文cocos2d-x版本为3.14,3之后的版本差别不会很大 Python环境 由于需要用到几个.py文件建立工程,我们要先设置好python2.x的环境 python官网下载,在找到2.x的版本的 ...
- ReentrantLock源码学习总结 (一)
[^ ]: 以下源码分析基于JDK1.8 ReentrantLock 示例 private ReentrantLock lock = new ReentrantLock(true); public v ...
- Java字符串课后作业
[实验任务] 1.实验题目:字串加密 2.实验内容:古罗马皇帝凯撒在打仗时曾经使用过以下方法加密军事情报:
- BZOJ [Scoi2015]情报传递
Description 奈特公司是一个巨大的情报公司,它有着庞大的情报网络.情报网络中共有n名情报员.每名情报员口J-能有 若T名(可能没有)下线,除1名大头日外其余n-1名情报员有且仅有1名上线.奈 ...
- MacOS 导入MySQLdb 报错解决思路(解决ImportError: this is MySQLdb version (1, 2, 3, 'beta', 1), but _mysql is version (1, 2, 5, 'final', 1))
cd /Library/Python/2.7/site-packages ls rm -rf MySQL_python-1.2.5-py2.7.egg-info 然后重新import 即可