sparkDag源码分析–生成
Dag生成
dag主要是通过rdd的各种转换生成,如下面rdd的map方法,会生成一个新的Rdd
//返回一个新的rdd,通过应用一个函数到Rdd的所有元素
def map[U: ClassTag](f: T => U): RDD[U] = {
val cleanF = sc.clean(f)
new MapPartitionsRDD[U, T](this, (context, pid, iter) => iter.map(cleanF))
}
多个这样的方法(算子)就生成了一个有向无环图Dag(Directed acyclic graph),如下图最左边的部分
![]()
下面来看一下几个相关的类
RDD
abstract class RDD[T: ClassTag](
@transient private var _sc: SparkContext,
@transient private var deps: Seq[Dependency[_]] //依赖
) extends Serializable with Logging {
//这个构造方法被下面的MapPartitionsRDD使用,map算子就只依赖前面一个RDD
def this(@transient oneParent: RDD[_]) =
this(oneParent.context , List(new OneToOneDependency(oneParent)))
//这个方法默认为deps,但是不同的子类实现是不同的,注意,这里
//返回的是一个Seq,表示一个rdd的依赖可能有多个,比如 c = a join b
//那么 c的依赖就有 a 和 b 了,这种rdd下面会讲到的
protected def getDependencies: Seq[Dependency[_]] = deps
}
MapPartitionsRDD OneToOneDependency
// map算子会生成MapPartitionsRDD 是Rdd的一个子类,它实现的就是默认的getDependencies
//方法
private[spark] class MapPartitionsRDD[U: ClassTag, T: ClassTag](
prev: RDD[T],
f: (TaskContext, Int, Iterator[T]) => Iterator[U], // (TaskContext, partition index, iterator)
preservesPartitioning: Boolean = false)
extends RDD[U](prev) {}
ShuffledRDD ShuffleDependency
// groupByKey算子会生成ShuffledRDD
//构造方法传了一个Nil,进去了,难道shuffleDependency没有依赖?
//它重写了getDependencies,里面new ShuffleDependency,使用的是prev变量,
class ShuffledRDD[K, V, C](
@transient var prev: RDD[_ <: Product2[K, V]],
part: Partitioner)
extends RDD[(K, C)](prev.context, Nil) {
override def getDependencies: Seq[Dependency[_]] = {
List(new ShuffleDependency(prev, part, serializer, keyOrdering, aggregator, mapSideCombine))
}
}
CoGroupedRDD OneToOneDependency/ShuffleDependency
//join算子会生成CoGroupedRDD
//CoGroupedRDD,它的getDependencies,会生成多个Dependency,join里面
//可能有OneToOneDependency/ShuffleDependency
class CoGroupedRDD[K](@transient var rdds: Seq[RDD[_ <: Product2[K, _]]], part: Partitioner)
extends RDD[(K, Array[Iterable[_]])](rdds.head.context, Nil) {
override def getDependencies: Seq[Dependency[_]] = {
rdds.map { rdd: RDD[_ <: Product2[K, _]] =>
if (rdd.partitioner == Some(part)) {
logDebug("Adding one-to-one dependency with " + rdd)
new OneToOneDependency(rdd)
} else {
logDebug("Adding shuffle dependency with " + rdd)
new ShuffleDependency[K, Any, CoGroupCombiner](rdd, part, serializer)
}
}
}
}
通过上面的代码,我们知道了再Rdd之间的转换,是通过不断生成新的Rdd,来构成一幅Dag
图的,Rdd与Rdd之间有OneToOneDependency/ShuffleDependency(切分的依据)