spark核心构件之Dependency(依赖)

之前的文章spark源码-rdd是如何运行的说一个spark任务其实就是一系列rdd构成的有向无环图(dag),今天我们来看看,spark是如何表示rdd之间的依赖关系建立这个dag的。

一、rdd如何构成dag

上篇文章spark核心构件之partitioner讲到了Partition和Partitioner知道了rdd是由一系列分区(partition)组成的,rdd之间的关系主要的其实就是分区之间的关系,也就是子rdd的某个分区数据需要依赖哪些rdd的哪些分区计算得到。

spark将rdd之间的关系抽象成了Dependency这个类,用于连接父子rdd,子rdd持有Dependency对象,Dependency对象里包含了父rdd。也就是dag的构成就像下面这样rdd1是rdd2和rdd3的子rdd

二、Dependency的定义

abstract class Dependency[T] extends Serializable {

def rdd: RDD[T]

}

只包含了一个rdd,就是父rdd的对象了 。Dependency有两个子类就是大家熟悉的款依赖和窄依赖了。

三、窄依赖 NarrowDependency

abstract class NarrowDependency[T](_rdd: RDD[T]) extends Dependency[T] {

def getParents(partitionId: Int): Seq[Int]

override def rdd: RDD[T] = _rdd

}

这是窄依赖的定义,一看就知道它想干嘛了是吧,就一个getParents函数,给一个子rdd的partitionId输出所依赖的父rdd的partitionId。

我们还能知道代表partition的其实就是一个int值的partitionId。

我们还能知道只有通过子rdd的partition才能知道依赖的父rdd的partition,而不能通过父rdd得到子rdd,这就说明rdd得计算方式只能是从子rdd向上遍历进行计算。

窄依赖有两个子类一个是OneToOneDependency

class OneToOneDependency[T](rdd: RDD[T]) extends NarrowDependencyT {

override def getParents(partitionId: Int): List[Int] = List(partitionId)

}

很明显就是一一对应,子rdd的一个partitionid就依赖一个父rdd同样的partitionid

另一个窄依赖的子类RangeDependency只用于union的时候,子rdd会有多个依赖每一个依赖都指向一个父rdd,大家可以先想想如果是你,你会怎么去实现多个rdd的union。

四、宽依赖 ShuffleDependency

class ShuffleDependency[K: ClassTag, V: ClassTag, C: ClassTag](

@transient private val rdd: RDD[ <: Product2[K, V]],

val partitioner: Partitioner,

val serializer: Serializer = SparkEnv.get.serializer,

val keyOrdering: Option[Ordering[K]] = None,

val aggregator: Option[Aggregator[K, V, C]] = None,

val mapSideCombine: Boolean = false,

val shuffleWriterProcessor: ShuffleWriteProcessor = new ShuffleWriteProcessor)

extends Dependency[Product2[K, V]] {

……

override def rdd: RDD[Product2[K, V]] = _rdd.asInstanceOf[RDD[Product2[K, V]]]

val shuffleId: Int = _rdd.context.newShuffleId()

val shuffleHandle: ShuffleHandle = _rdd.context.env.shuffleManager.registerShuffle(

shuffleId, _rdd.partitions.length, this)

}

上面就是ShuffleDependency的定义了,Dependency对象里面包含父rdd的对象,DAGScheduler在进行stage划分和task分配的时候就可以通过Dependency获取shuffleWriter写数据了。

子rdd持有这个Dependency对象,子rdd就可以通过它获得shuffle信息拉取上个stage的数据。

五、总结

Dependency是rdd之间的连接,表达了子rdd在计算某个partition的时候应该去哪个rdd的哪个partitions取数据。Dependency又分宽窄依赖,而宽依赖包含了shuffle信息,父rdd通过它写数据,子rdd通过它获取数据。

相关文章:

五分钟加简历-精通sparksql源码

spark核心构件之partitioner

spark源码-rdd是如何运行的

【解答】sql和其他语言的思考方式

  大连无痛人流 http://www.dlwtrlyy.com/

  大连妇科医院医生团队 http://www.62671288.com/

  大连包皮手术多少钱 http://www.39836828.com/

猜你喜欢

转载自blog.csdn.net/qq_42894764/article/details/88911240