先上一张图整体了解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分为两种

  1. BarrierBuffer
  2. 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. 1处是一个用于Encoder 的ChannelOutboundHandler常规的编码器没有什么好说的
  2. 2处是用于Decoder的ChannelinboundHandler常规的解码器没有什么好说的

  3. 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机制 (源码分析)的更多相关文章

  1. Flink中发送端反压以及Credit机制(源码分析)

    上一篇<Flink接收端反压机制>说到因为Flink每个Task的接收端和发送端是共享一个bufferPool的,形成了天然的反压机制,当Task接收数据的时候,接收端会根据积压的数据量以 ...

  2. Flink中TaskManager端执行用户逻辑过程(源码分析)

    TaskManager接收到来自JobManager的jobGraph转换得到的TDD对象,启动了任务,在StreamInputProcessor类的processInput()方法中 通过一个whi ...

  3. Springboot学习04-默认错误页面加载机制源码分析

    Springboot学习04-默认错误页面加载机制源码分析 前沿 希望通过本文的学习,对错误页面的加载机制有这更神的理解 正文 1-Springboot错误页面展示 2-Springboot默认错误处 ...

  4. ApplicationEvent事件机制源码分析

    <spring扩展点之三:Spring 的监听事件 ApplicationListener 和 ApplicationEvent 用法,在spring启动后做些事情> <服务网关zu ...

  5. Android事件分发机制源码分析

    Android事件分发机制源码分析 Android事件分发机制源码分析 Part1事件来源以及传递顺序 Activity分发事件源码 PhoneWindow分发事件源码 小结 Part2ViewGro ...

  6. Flink中Idle停滞流机制(源码分析)

    前几天在社区群上,有人问了一个问题 既然上游最小水印会决定窗口触发,那如果我上游其中一条流突然没有了数据,我的窗口还会继续触发吗? 看到这个问题,我蒙了???? 对哈,因为我是选择上游所有流中水印最小 ...

  7. 时间轮机制在Redisson分布式锁中的实际应用以及时间轮源码分析

    本篇文章主要基于Redisson中实现的分布式锁机制继续进行展开,分析Redisson中的时间轮机制. 在前面分析的Redisson的分布式锁实现中,有一个Watch Dog机制来对锁键进行续约,代码 ...

  8. Servlet容器Tomcat中web.xml中url-pattern的配置详解[附带源码分析]

    目录 前言 现象 源码分析 实战例子 总结 参考资料 前言 今天研究了一下tomcat上web.xml配置文件中url-pattern的问题. 这个问题其实毕业前就困扰着我,当时忙于找工作. 找到工作 ...

  9. 【Cocos2d-x 3.x】 事件处理机制源码分析

    在游戏中,触摸是最基本的,必不可少的.Cocos2d-x 3.x中定义了一系列事件,同时也定义了负责监听这些事件的监听器,另外,cocos定义了事件分发类,用来将事件派发出去以便可以实现相应的事件. ...

随机推荐

  1. Activity的四种加载模式详解:

    先来看看总结图: 模式详解: standard模式: 标准启动模式,也是activity的默认启动模式.在这种模式下启动的activity可以被多次实例化,即在同一个任务中可以存在多个activity ...

  2. idea 新建项目 coding上新建项目 idea推送到coding

    1. 注册coding a. 首先在(https://coding.net)上创建项目 ps:跳过注册 ![file](https://img2018.cnblogs.com/blog/1416679 ...

  3. 09-01 Tensorflow1基本使用

    目录 Tensorflow基本使用 一.确认安装Tensorflow 二.获取MNIST数据集 三.使用Tensorflow训练--Softmax回归 四.使用Tensorflow训练--卷积神经网络 ...

  4. 10月27日Java整理

    实验一:凯撒密码 import java.util.Scanner; //zhanxinwu,October,25,2016 public class Addmi { public static vo ...

  5. JZOJ10004 列车调度

    [JZOJ100041]列车调度 Description Input Output Sample Input Sample1: 3 1 2 3 Sample2: 9 1 3 2 4 8 6 9 5 7 ...

  6. Pandas处理日常EXCEL表格的便捷操作

    第一次写博客,写的可能有点乱,有问题可以一起探讨.格式可能控制也不是太好. 1.日常的数据集大多带有中文格式,例如“公务员招聘岗位汇总.xls”.我们使用pandas的read_csv()函数读取可能 ...

  7. CS184.1X 计算机图形学导论 第3讲L3V1

    二维空间的变换 L3V1这一课主要讲了二维空间的变换,包括平移.错切和旋转. 缩放 缩放矩阵 使用矩阵的乘法来完成缩放 缩放矩阵是一个对角矩阵,对角线上的值对应缩放倍数 错切(shear) 错切可以将 ...

  8. shark恒破解笔记3-EAX决定胜负

    PEID查壳 od载入 输入假的注册码 查找出错字符串 往上查找是否有关键跳转和关键call 可以看到此处有个je跳转 实现了跳转,并且跳过了我们注册成功的地址 网上查找这个跳转的关键call,这个c ...

  9. GDAL集成对KML文件的支持

    目录 1. 正文 1.1. 编译LibKML 1.1.1. 第三方库支持 1.1.2. 编译错误 1.2. 配置GDAL 1.3. 链接问题 2. 参考 1. 正文 GDAL可以支持将KML作为矢量文 ...

  10. std::multimap

    标准库还定义了一个 multimap 容器,它与 map 类似,所不同的是它允许重复键. 成员函数 insert() make_pair() 辅助函数来完成此任务. find(k) 返回指向第一个与键 ...