RDD
A Resilient Distributed Dataset (RDD).
一个弹性的分布式数据集合。
RDD数据集有5个主要的属性:
在RDD的源码内部,有以下注释,理解即可。
- 有分区列表,指RDD这个对象中,是知道各个分区数据在分布式文件系统中的哪个位置。
- 有相同的函数可以用于计算每个切片的数据
- 有该RDD数据集合所依赖的数据集合列表
- 可选的,可以有对Key-Value进行分区操作的分区器(例如:默认是hash值分区)
- 可选的,RDD会更加偏向于数据本地化计算(在每个切片所在的位置进行数据的计算可以减少数据移动,增加了效率)
从源码角度理解RDD
要读源码,首先要确定一个具体的流程,以用于贯穿整个阅读路线,我们就以从HDFS中读取文件并作一个
WordCount
为例子,代码这边不再复述。
我们先粗略看一下RDD这个类有什么属性和方法:
其中
_sc
的作用是指向一个SparkContext
对象,便于每个RDD在运行中拿到本次程序的上下文;
deps
的作用是用于记录这个RDD数据集依赖于哪些RDD数据集。
compute()
方法是用于RDD数据集的计算使用,运用了迭代器模式。
abstract class RDD[T: ClassTag](
@transient private var _sc: SparkContext,
@transient private var deps: Seq[Dependency[_]]
) extends Serializable with Logging {
@DeveloperApi
def compute(split: Partition, context: TaskContext): Iterator[T]
}
要读源码,首先要明白其流程:
当我们要写一个简单的MR程序时,较普通的操作就是从HDFS中去拉取数据,于是我们试着通过SparkContext.hadoopFile()
方法去追溯其具体源码,可以发现:
def hadoopFile[K, V](
path: String,
inputFormatClass: Class[_ <: InputFormat[K, V]],
keyClass: Class[K],
valueClass: Class[V],
minPartitions: Int = defaultMinPartitions): RDD[(K, V)] = withScope {
assertNotStopped()
... ...
new HadoopRDD(
this,
confBroadcast,
Some