Spark的RDD详解和自定义RDD(源码)

RDD概论

具体概念百度(以下总结): 
Spark中 RDD本身并不是数据,只是数据信息的集合。 
getPartitions只运行一次; 
compute每次有action算子的时候都会运行,一个partition一次。

NewHadoopRDD

Jobid

Spark的RDD详解和自定义RDD(源码)

Partition

获取分区的方式,是根据inputFormatClass的反射获取inputFormat类来获取分区,获取split信息,然后new几个NewHadoopPartition(个数等于分区数)。一般自定义的Partition都没什么东西,都是一些partition的信息(例如数据的开始结束offset,主要是在获取数据时提供信息) 
Spark的RDD详解和自定义RDD(源码)

Compute (实际读取数据的方式)

读取数据使用compute方法(传入分区信息和task信息),返回一个Iterator。这里直接new一个Iterator,里面直接重写他的next等方法。(每次调用compute的时候,都会启动一个task任务) 
Spark的RDD详解和自定义RDD(源码) 
获取分片的信息和对应分片的RecordReader(InputFormat里面的(写MR有时候要重写这个RecordReader))来读取数据,到这里已经把数据的读取都准备好了。 
已经返回一个Iterator了。。调用Iterator的next就能得到这个分区的数据 
Spark的RDD详解和自定义RDD(源码) 
Spark的RDD详解和自定义RDD(源码)

RDD的依赖

Spark的RDD详解和自定义RDD(源码) 
刚开始生成RDD的时候会传入一个sc和一个seq[Dependencies](依赖关系),第二个一般为Nil(如果没有父依赖的话),可以查看HadoopRDD。 
在自定义RDD时,如果是由parent(父依赖)生成的,需要传入一个父 RDD。分区信息可以使用parent的,数据的获取方式可以自己决定,在compute里。数据可以是从 parent.里面获取也可以自己重新载入(上图的例子中,将parent的对应的分区的数据进行data+”@”+x处理)。 
参考:http://blog.sina.com.cn/s/blog_3eb4ed710102vzri.html

继承RDD有两种构造方法

无父依赖的RDD定义

比如生成HadoopRDD的时候就是继承的这个构造方法 
Spark的RDD详解和自定义RDD(源码) 
Nil是依赖关系,初始为空。把下面这个图的extends RDD和上面的对应。可以发现,这个HadoopRDD继承自RDD(K,V) 
Spark的RDD详解和自定义RDD(源码)

有父依赖的RDD定义

比如使用map,filter等窄依赖的时候。其实内部也是调用的上面的方法,但是依赖使用了父RDD的 
Spark的RDD详解和自定义RDD(源码) 
可以查看MapPartitionsRDD这个RDD。可以看到这个RDD是继承自RDDU跟上面的HadoopRDD不一样。其实是一样的。他调用的是上面这个图,最终继承的也是最上面的那个图 
Spark的RDD详解和自定义RDD(源码)

多父依赖的RDD定义

以下是join操作中生成的CoGroupedRDD的获取父依赖 
Spark的RDD详解和自定义RDD(源码) 
Spark的RDD详解和自定义RDD(源码)