感谢DT大数据梦工厂支持提供技术支持,DT大数据梦工厂专注于Spark发行版定制。

本期概览:

解读RDD的生命周期

1 DStream与RDD关系的彻底的研究

2 StreamingRDD的生成彻底研究

我们有必要来思考三个重要有价值的问题:

1 DStream生成RDD的过程,DStream到底是怎么生成RDD的?

2 DStream和RDD到底什么关系?

3 RDD生成后是怎么管理的

后期我们会结合一个大型的项目(大到可以重建一个京东),更加清晰的深入理解源码。敬请期待。

从以下代码开始(一个在线黑名单过滤代码(用到广播,计数器))


注意:广播和计数器并不像看上去那么简单,在实际的最佳实践中,通过广播和计数器可以实现非常复杂的算法。非常有用。

1 进入源码部分print()

1.1


解释:这里的print源码内部用foreachRDD将通过foreachFunc构建的(RDD,Time)遍历操作。

3 foreachRDD其实也是要产生ForEachDStream,对DStream遍历操作,ForEachDStream不会产生action操作,所以ForEachDStream操作是transform级别操作。所以我们得出一个结论:ForEachDStream并不一定会触发job的执行,但是会产生Job,(不会触发执行)(真正的job触发是Timer定时产生的额)

ForEachDStream会产生Job其实也是假像,因为没有ForEachDStream,也会产生job,定时器Timer时间到了,管你有没有ForEachDStream,还是会产生job并执行。

 

我们再来看一下foreachRDD


可以这样说:foreachRDD是Spark Streaming的后门,实际上可以任意操作RDD(表面上是DStream离散流数据)

为了弄清楚DStream怎样生成RDD的,我们需要看DStream的源代码,如下所示


这里一共有三个关键重点:

    1 除了第一个DStream,后面的DStream都要依赖前一个DStream.

    2 DStream在每一个interval都会生成一个RDD.

    3 这个类里有个function可以在每一个interval后产生一个RDD.

这里再次强调:DStream是RDD的模板,负责批量产生RDD。那么接下来,我们彻底深入查看具体过程。

4 以官方WordCount代码为例:

四个步骤实际上都是transform(表面上最后一个是action)


额外强调一下:为什么DStream要像RDD一样回溯,从后往前依赖,构建最后一个DStream?因为DStream要根据batch interval每隔一定时间产生RDD,必须和RDD高度步调一致(其实可以不一致,只不过会有很多问题)。

这样又说明了:DStream是RDD模板,DStream Graph是DAG的模板。

 

之前是RDD生成的逻辑级别的背景铺垫。接下来,我们着手物理级别的实际RDD生成过程;具体如下

上图是基于时间的RDD数据结构

一个RDD(实际代表最后一个RDD)意味着会执行一个job。

如果弄清楚GenerateRDD是怎么实列化的,就可以弄清楚RDD到底是怎么产生的了。

如下:DStream类中


判断时间是否有效等等


回溯产生的新的RDD

到此处,RDD变量生成了,但是并没有执行,只是在逻辑级别进行了代码的框架级别的优化管理。

注意:SparkStreaming实际上在没有输入数据的时候仍然会产生RDD,(空的BlockRDD),所以可以在此修改源码,提升性能。反过来仔细思考一下,流处理实际上又是时间极短的情况下完成的批处理。

SocketInputDStream因为是第一个DStream,幼无所依,所以必须要自己生成RDD

 

graph.generateJobs


输出流调度job

posted on 2016-05-14 12:46  lilingui  阅读(119)  评论(0)    收藏  举报