原创文章,转载请注明:转载自 听风居士博客(http://www.cnblogs.com/zhouyf/)  
在上一篇中介绍了Receiver的整体架构和设计原理,本篇内容主要介绍Receiver在Executor中数据接收和存储过程

一、Receiver启动过程回顾

如图,从ReceiverTracker的start方法开始,调用launchReceivers()方法,给endpoint发送消息,endpoint.send(StartAllReceivers(receivers)),endpoint就是ReceiverTrackerEndpoint,ReceiverTrackerEndpoint调用startReceiver方法在Executor中启动ReceiverSupervisor。详情请阅读链接中的文章http://blog.csdn.net/zhouzx2010

二、Receiver数据接收全过程总览
    Receiver数据接收核心成员:
    1.ReceiverSupervisor
    2.BlockGenerator
    3.Receiver
    4.ReceiverTracker    
    5.BlockManager
    首先ReceiverSupervisor启动,继而启动BlockGenerator和Receiver,其中BlockGenerator首先启动一个定时器定时将接收的数据封装成Block,然后启动一个线程不断将Block数据推送给BlockManager。而Receiver启动后不断接收数据,并不断将接受的数据添加到BlockGenerator中,这样BlockGenerator就不断将Receiver接收的数据推送到BlockManager,整个数据接收过程如下图:





三、Receiver数据接收过程详解
    3.1 ReceiverSupervisor 启动

       Spark Streaming 在集群启动Receiver的时候会先在Executor中启动ReceiverSupervisor来管理Receiver,ReceiverSupervisor的启动是通过调用他的start方法完成的,源码如下:


ReceiverSupervisor的start方法首先调用了onStart 方法,该方法启动了BlockGenerator,必须在启动Receiver之前调用该方法来启动BlockGenerator,因为必须BlockGenerator先启动,以保证接收到的数据能够被存储起来。该方法在ReceiverSupervisor的子类ReceiverSupervisorImpl有实现:



可以看到,在onStart方法中启动了所有的已经注册的BlockGenerator,其中registeredBlockGenerators是ReceiverSupervisorImpl的成员变量,在ReceiverSupervisorImpl实例化是被创建:



registeredBlockGenerators中的Generartor是什么时候产生,并加入到registeredBlockGenerators这个队列里的呢?ReceiverSupervisorImpl的createBlockGenerator方法对registeredBlockGenerators进行了元素添加:



从源码可以看到每一个receiver创建一个BlockGenerator,因为streamId与receiver一一对应。createBlockGenerator首先还将已经停止的BlockGenerator从registeredBlockGenerators队列清除。createBlockGenerator 方法又是在什么时候被调用的呢,答案是在ReceiverSupervisorImpl实例化时候被调用,请看源码:



现在registeredBlockGenerators中有了BlockGenerator,接下来分析BlockGenerator的启动过程

 3.2 BlockGenerator 启动



BlockGenerator的start方法启动一个定时器blockIntervalTimer,用来定时生成调用updateCurrentBuffer方法:



时间间隔默认是200毫秒:



下面看一下updateCurrentBuffer的源码:



currentBuffer 是一个ArrayBuffer 存储了数据记录,updateCurrentBuffer方法将间隔时间段的数据记录封装成Block,然后将新的Block 放入等待推送的block队列blockForPushing:



回到BlockGenerator的start方法的另一个线程blockPushingThread



可以看到blockPushingThread的run方法调用了keepPushingBlocks方法将blockForPushing队列中的Block推送给BlockManager:



可以看到最多等待10毫秒从blockForPushing中取去Block,然后掉pushBlock方法将block推送给BlockManager,下面看一下pushBlock的源码



这里的listener 是 BlockGeneratorListener 对象,在ReceiverSupervisorImpl中被实例化:



我们关注其中的onPushBlock方法:调用了pushArrayBuffer方法:


这里调用了一个很重要的方法
pushAndReportBlock
我们看一下源码:



pushAndReportBlock方法用来存储接收的的数据Block并将元数据汇报给ReceiverTracker。
Block存储交给receivedBlockHandler处理,receivedBlockHandlery有两种实现方式:



看一下BlockManagerBasedBlockHandler的storeBlock方法:



BlockManagerBasedBlockHandler的storeBlock方法根据ReceivedBlock的不同类型分别处理,最终都是交给了BlockManger管理。
至此BlockGenerator 分析完毕,下面分析 Receiver 的启动过程

3.3 Receiver 启动
首先回到ReceiverSupervisorImpl的startReceiver方法:



首先调用了onReceiverStart方法,将Receiver注册给ReceiverTracker,重点看代码rever.onStart(),调用了receiver的onStart方法,此处我们以SocketReceiver为例进行讲解:



可以看到SocketReceiver的onStart()方法先给创建了一个Socket对象赋值给了socket,然后启动了一个后台进行“Socket Receiver” ,在后台进程的run方法中调用了receive()方法进行数据接收:



SocketReceiver的receive()方法不断从socket接收数据,然后调用store方法进行存储。



此处再次回到ReceiverSupervisor,调用了其中的pushSingle函数:



最终调用了BlockGenerator的addData方法:



可以看到BlockGenerator的addData方法将数据添加到currentBuffer中,然后blockIntervalTimer会每个200毫秒从currentBuffer取出数据封装成Block,并将Block添加到blockForPushing队列,blockPushingThread会将blockForPushing队列中的block推送给BlockManager。至此Receiver运行流程分析完毕。

四、总结:receiver数据接收流程图
    总体过程:ReceiverSupervisor启动时,启动了BlockGenerator和Receiver,其中BlockGenerator首先启动一个定时器定时将接收的数据封装成Block,然后启动一个线程不断将Block数据推送给BlockManager。而Receiver启动后不断接收数据,不断将接受的数据添加到BlockGenerator的currentBuffer中,BlockGenerator不断从currentBuffer取数据,这样整个数据接收过程不断循环。



原创文章,转载请注明:转载自 听风居士博客(http://www.cnblogs.com/zhouyf/)  





10.Spark Streaming源码分析:Receiver数据接收全过程详解的更多相关文章

  1. 16.Spark Streaming源码解读之数据清理机制解析

    原创文章,转载请注明:转载自 听风居士博客(http://www.cnblogs.com/zhouyf/) 本期内容: 一.Spark Streaming 数据清理总览 二.Spark Streami ...

  2. ZRender源码分析5:Shape绘图详解

    回顾 上一篇说到:ZRender源码分析4:Painter(View层)-中,这次,来补充一下具体的shape 关于热区的边框 以圆形为例: document.addEventListener('DO ...

  3. jQuery 源码分析(十八) ready事件详解

    ready事件是当DOM文档树加载完成后执行一个函数(不包含图片,css等),因此它的触发要早于load事件.用法: $(document).ready(fun) ;fun是一个函数,这样当DOM树加 ...

  4. jQuery 源码分析(十一) 队列模块 Queue详解

    队列是常用的数据结构之一,只允许在表的前端(队头)进行删除操作(出队),在表的后端(队尾)进行插入操作(入队).特点是先进先出,最先插入的元素最先被删除. 在jQuery内部,队列模块为动画模块提供基 ...

  5. vuex 源码分析(七) module和namespaced 详解

    当项目非常大时,如果所有的状态都集中放到一个对象中,store 对象就有可能变得相当臃肿. 为了解决这个问题,Vuex允许我们将 store 分割成模块(module).每个模块拥有自己的 state ...

  6. Jvm(jdk8)源码分析1-java命令启动流程详解

    JDK8加载源码分析 1.概述 现在大多数互联网公司都是使用java技术体系搭建自己的系统,所以对java开发工程师以及java系统架构师的需求非常的多,虽然普遍的要求都是需要熟悉各种java开发框架 ...

  7. Netty源码分析之Reactor线程模型详解

    上一篇文章,分析了Netty服务端启动的初始化过程,今天我们来分析一下Netty中的Reactor线程模型 在分析源码之前,我们先分析,哪些地方用到了EventLoop? NioServerSocke ...

  8. Spark Streaming源码分析 – Checkpoint

    PersistenceStreaming没有做特别的事情,DStream最终还是以其中的每个RDD作为job进行调度的,所以persistence就以RDD为单位按照原先Spark的方式去做就可以了, ...

  9. Spark Streaming源码分析 – JobScheduler

    先给出一个job从被generate到被执行的整个过程在JobGenerator中,需要定时的发起GenerateJobs事件,而每个job其实就是针对DStream中的一个RDD,发起一个Spark ...

随机推荐

  1. Qt ------ QProcess,启动外部进程,进程间通信

    简介: 可用于完成启动外部程序,并与之交互通信. 启动一个进程的名字叫“program”,如果某进程的路径没有设置成环境变量,“program”需要包含路径 如果进程可以接收参数,参数叫“argume ...

  2. spring boot 2.0.3+spring cloud (Finchley)9、 安全组件Spring Boot Security

    官方文档 一.Spring Security介绍 Spring Security是Spring Resource社区的一个安全组件,Spring Security为JavaEE企业级开发提供了全面的安 ...

  3. debian自动挂载ntfs硬盘

    首先下载安装ntfs-3g apt-get install ntfs-3g 然后查看分区信息 fdisk -l Device Boot Start End Blocks Id System /dev/ ...

  4. Spring Boot 使用IntelliJ IDEA创建一个web开发实例(一)

    .新建项目File-->New-->Project-->Spring Initializr 点击Finish,一个Spring Boot web应用就创建好了.

  5. Digging(DP)

    ZOJ Problem Set - 3689 Digging Time Limit: 2 Seconds      Memory Limit: 65536 KB When it comes to th ...

  6. cin.getline()与getline()

    C++中有两个getline函数, cin.getline()与getline()  这两个函数相似,但是 这两个函数分别定义在不同的头文件中.   cin.getline()属于istream流,而 ...

  7. 数据库 插入时 碰到NULL报错判断的一种方法(技巧)

    //public static object ToDBNull(object value) 判断插入数据的时候个别参数不能为空的时候做的判断方法 //{ // if (value == null) / ...

  8. 周末发福利了!26个免费的HTML5模版

    本期文章我们为大家搜集了很多专业且高质量的HTML5模版,而且还是免费的呦.如果你对编码很熟悉,那么从这些网站里你可以学到很多新技能.来这些国际范的案例中挑选您喜欢的模版学习起来吧:) Zeences ...

  9. 【BZOJ】1901: Zju2112 Dynamic Rankings

    [题意]带修改的查询区间第k小 [算法]树状数组套可持久化线段树 [题解]对于树状数组上的每个节点,维护可持久化权值线段树(节点为权值),从而达到查询前缀和的目的. 对于每次修改,在待修改线段树基础上 ...

  10. composer 上提交自己的包

    先在github上复制自己的地址在 https://packagist.org/packages/submit ->check->submit