在上一篇中介绍了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取数据,这样整个数据接收过程不断循环。

- 16.Spark Streaming源码解读之数据清理机制解析
原创文章,转载请注明:转载自 听风居士博客(http://www.cnblogs.com/zhouyf/) 本期内容: 一.Spark Streaming 数据清理总览 二.Spark Streami ...
- ZRender源码分析5:Shape绘图详解
回顾 上一篇说到:ZRender源码分析4:Painter(View层)-中,这次,来补充一下具体的shape 关于热区的边框 以圆形为例: document.addEventListener('DO ...
- jQuery 源码分析(十八) ready事件详解
ready事件是当DOM文档树加载完成后执行一个函数(不包含图片,css等),因此它的触发要早于load事件.用法: $(document).ready(fun) ;fun是一个函数,这样当DOM树加 ...
- jQuery 源码分析(十一) 队列模块 Queue详解
队列是常用的数据结构之一,只允许在表的前端(队头)进行删除操作(出队),在表的后端(队尾)进行插入操作(入队).特点是先进先出,最先插入的元素最先被删除. 在jQuery内部,队列模块为动画模块提供基 ...
- vuex 源码分析(七) module和namespaced 详解
当项目非常大时,如果所有的状态都集中放到一个对象中,store 对象就有可能变得相当臃肿. 为了解决这个问题,Vuex允许我们将 store 分割成模块(module).每个模块拥有自己的 state ...
- Jvm(jdk8)源码分析1-java命令启动流程详解
JDK8加载源码分析 1.概述 现在大多数互联网公司都是使用java技术体系搭建自己的系统,所以对java开发工程师以及java系统架构师的需求非常的多,虽然普遍的要求都是需要熟悉各种java开发框架 ...
- Netty源码分析之Reactor线程模型详解
上一篇文章,分析了Netty服务端启动的初始化过程,今天我们来分析一下Netty中的Reactor线程模型 在分析源码之前,我们先分析,哪些地方用到了EventLoop? NioServerSocke ...
- Spark Streaming源码分析 – Checkpoint
PersistenceStreaming没有做特别的事情,DStream最终还是以其中的每个RDD作为job进行调度的,所以persistence就以RDD为单位按照原先Spark的方式去做就可以了, ...
- Spark Streaming源码分析 – JobScheduler
先给出一个job从被generate到被执行的整个过程在JobGenerator中,需要定时的发起GenerateJobs事件,而每个job其实就是针对DStream中的一个RDD,发起一个Spark ...
随机推荐
- shell unittest工具
shUnit2: https://github.com/kward/shunit2 用法非常简单,看看readme就行了.
- 手脱ASPack v2.12变形壳2
1.PEID载入 ASPack v2.12 2.载入OD,跟之前帖子的入口特征相同,都是一个pushad,但是请不要怀疑这是同一个壳,绝对不是,pushad下一行ESP定律下硬件断点,然后shift+ ...
- [吴恩达机器学习笔记]14降维5-7重建压缩表示/主成分数量选取/PCA应用误区
14.降维 觉得有用的话,欢迎一起讨论相互学习~Follow Me 14.5重建压缩表示 Reconstruction from Compressed Representation 使用PCA,可以把 ...
- 2015年IPC网络摄像机技术发展现状分析
网络摄像机将图像转换为基于TCP/IP网络标准的数据包,使摄像机所摄的画面通过RJ-45以太网接口或WIFI WLAN无线接口直接传送到网络上,通过网络即可远端监视画面. 一.网络摄像机的基本原理 网 ...
- spring boot 2.0.3+spring cloud (Finchley)5、路由网关Spring Cloud Zuul
Zuul作为微服务系统的网关组件,用于构建边界服务,致力于动态路由.过滤.监控.弹性伸缩和安全. 为什么需要Zuul Zuul.Ribbon以及Eureka结合可以实现智能路由和负载均衡的功能:网关将 ...
- LightOJ 1088 - Points in Segments 二分
http://www.lightoj.com/volume_showproblem.php?problem=1088 题意:给出N个点,Q个查询,问在区间内的点数有多少个. 思路:直接在线二分,注意边 ...
- Flying to the Mars
D - Flying to the Mars Time Limit:1000MS Memory Limit:32768KB 64bit IO Format:%I64d & %I ...
- 【NOIP】普及组2009 细胞分裂
[算法]数论 [题解]均分的本质是A整除B,A整除B等价于A的质因数是B的子集. 1.将m1分解质因数,即m1=p1^a1*p2^a2*...*pk^ak 所以M=m1^m2=p1^(a1*m2)*p ...
- 使用 pjax 载入的新页面,新页面上 类方法 无法被触发?
在父页面上有定义类似 $(".class").click(function(){ ... }) 经过pjax 载入后的新页面 点击后没有触发事件 在segmentfault 上提问 ...
- N-gram语言模型与马尔科夫假设关系(转)
1.从独立性假设到联合概率链朴素贝叶斯中使用的独立性假设为 P(x1,x2,x3,...,xn)=P(x1)P(x2)P(x3)...P(xn) 去掉独立性假设,有下面这个恒等式,即联合概率链规则 P ...