Spark源码分析 – Dependency
Dependency
依赖, 用于表示RDD之间的因果关系, 一个dependency表示一个parent rdd, 所以在RDD中使用Seq[Dependency[_]]来表示所有的依赖关系
Dependency的base class
可见Dependency唯一的成员就是rdd, 即所依赖的rdd, 或parent rdd
/**
* Base class for dependencies.
*/
abstract class Dependency[T](val rdd: RDD[T]) extends Serializable
Dependency分为两种, narrow和shuffle
NarrowDependency
先看看比较简单的narrow
定义, parent RDD中的每个partition最多被child RDD中的一个partition使用, 即不需要shuffle
更直白点, 就是Narrow只有map, partition本身范围不会改变, 一个parititon经过transform还是一个partition, 虽然内容发生了变化, 所以可以在local完成
而wide就是, partition需要打乱从新划分, 存在shuffle的过程, partition的数目和范围都发生了变化
唯一的接口getParents, 即给定任一个partition-id, 得到所有依赖的parent partitions的id的seq
/**
* Base class for dependencies where each partition of the parent RDD is used by at most one
* partition of the child RDD. Narrow dependencies allow for pipelined execution.
*/
abstract class NarrowDependency[T](rdd: RDD[T]) extends Dependency(rdd) {
/**
* Get the parent partitions for a child partition.
* @param partitionId a partition of the child RDD
* @return the partitions of the parent RDD that the child partition depends upon
*/
def getParents(partitionId: Int): Seq[Int]
}
NarrowDependency又分为两种,
OneToOneDependency
最简单的依赖关系, 即parent和child里面的partitions是一一对应的, 典型的操作就是map, filter…
其实partitionId就是partition在RDD中的序号, 所以如果是一一对应, 那么parent和child中的partition的序号应该是一样的
/**
* Represents a one-to-one dependency between partitions of the parent and child RDDs.
*/
class OneToOneDependency[T](rdd: RDD[T]) extends NarrowDependency[T](rdd) {
override def getParents(partitionId: Int) = List(partitionId) //序号一致
}
RangeDependency
虽然仍然是一一对应, 但是是parent RDD中的某个区间的partitions对应到child RDD中的某个区间的partitions
典型的操作是union, 多个parent RDD合并到一个child RDD, 故每个parent RDD都对应到child RDD中的一个区间
需要注意的是, 这里的union不会把多个partition合并成一个partition, 而是的简单的把多个RDD中的partitions放到一个RDD里面, partition不会发生变化, 可以参考Spark 源码分析 – RDD 中UnionRDD的实现
由于是range, 所以直接记录起点和length就可以了, 没有必要加入每个中间rdd, 所以RangeDependency优化了空间效率
/**
* Represents a one-to-one dependency between ranges of partitions in the parent and child RDDs.
* @param rdd the parent RDD
* @param inStart the start of the range in the parent RDD, parent RDD中区间的起始点
* @param outStart the start of the range in the child RDD, child RDD中区间的起始点
* @param length the length of the range
*/
class RangeDependency[T](rdd: RDD[T], inStart: Int, outStart: Int, length: Int)
extends NarrowDependency[T](rdd) { override def getParents(partitionId: Int) = {
if (partitionId >= outStart && partitionId < outStart + length) { //判断partitionId的合理性,必须在child RDD的合理partition范围内
List(partitionId - outStart + inStart) //算出parent RDD中对应的partition id
} else {
Nil
}
}
}
WideDependency
WideDependency, 也称为ShuffleDependency
首先需要基于PairRDD, 因为一般需要依据key进行shuffle, 所以数据结构往往是kv
即RDD中的数据是kv pair, [_ <: Product2[K, V]],
trait Product2[+T1, +T2] extends Product // Product2 is a cartesian product of 2 components
Product2是trait, 这里实现了Product2可以用于表示kv pair? 不是很理解
其次, 由于需要shuffle, 所以当然需要给出partitioner, 如何完成shuffle
然后, shuffle不象map可以在local进行, 往往需要网络传输或存储, 所以需要serializerClass
最后, 每个shuffle需要分配一个全局的id, context.newShuffleId()的实现就是把全局id累加
/**
* Represents a dependency on the output of a shuffle stage.
* @param rdd the parent RDD
* @param partitioner partitioner used to partition the shuffle output
* @param serializerClass class name of the serializer to use
*/
class ShuffleDependency[K, V](
@transient rdd: RDD[_ <: Product2[K, V]],
val partitioner: Partitioner,
val serializerClass: String = null)
extends Dependency(rdd.asInstanceOf[RDD[Product2[K, V]]]) { val shuffleId: Int = rdd.context.newShuffleId()
}
Spark源码分析 – Dependency的更多相关文章
- Spark源码分析 – 汇总索引
http://jerryshao.me/categories.html#architecture-ref http://blog.csdn.net/pelick/article/details/172 ...
- Spark源码分析 – SparkContext
Spark源码分析之-scheduler模块 这位写的非常好, 让我对Spark的源码分析, 变的轻松了许多 这里自己再梳理一遍 先看一个简单的spark操作, val sc = new SparkC ...
- Spark源码分析之七:Task运行(一)
在Task调度相关的两篇文章<Spark源码分析之五:Task调度(一)>与<Spark源码分析之六:Task调度(二)>中,我们大致了解了Task调度相关的主要逻辑,并且在T ...
- Spark源码分析之五:Task调度(一)
在前四篇博文中,我们分析了Job提交运行总流程的第一阶段Stage划分与提交,它又被细化为三个分阶段: 1.Job的调度模型与运行反馈: 2.Stage划分: 3.Stage提交:对应TaskSet的 ...
- Spark源码分析之三:Stage划分
继上篇<Spark源码分析之Job的调度模型与运行反馈>之后,我们继续来看第二阶段--Stage划分. Stage划分的大体流程如下图所示: 前面提到,对于JobSubmitted事件,我 ...
- Spark源码分析之二:Job的调度模型与运行反馈
在<Spark源码分析之Job提交运行总流程概述>一文中,我们提到了,Job提交与运行的第一阶段Stage划分与提交,可以分为三个阶段: 1.Job的调度模型与运行反馈: 2.Stage划 ...
- spark 源码分析之十九 -- DAG的生成和Stage的划分
上篇文章 spark 源码分析之十八 -- Spark存储体系剖析 重点剖析了 Spark的存储体系.从本篇文章开始,剖析Spark作业的调度和计算体系. 在说DAG之前,先简单说一下RDD. 对RD ...
- spark源码分析以及优化
第一章.spark源码分析之RDD四种依赖关系 一.RDD四种依赖关系 RDD四种依赖关系,分别是 ShuffleDependency.PrunDependency.RangeDependency和O ...
- Spark源码分析(三)-TaskScheduler创建
原创文章,转载请注明: 转载自http://www.cnblogs.com/tovin/p/3879151.html 在SparkContext创建过程中会调用createTaskScheduler函 ...
随机推荐
- QQ连连看-外挂
QQ连连看-外挂 2014-11-06 参考 [1] [视频教程] c语言实践课程之qq连连看辅助开发 [2] CE工具下载 [3] [原创]qq连连看外挂制作详解
- 关于mysqli_free_result($result)报错
运行原来的一个原生的php写的项目,出现mysqli_free_result($result)的警告 Warning: mysqli_free_result() expects parameter 1 ...
- python右键不显示IDLE
打开注册表,在HKEY_CLASSES_ROOT\SystemFileAssociations中添加.py\shell\Edit with IDLE\command(右键 ->‘新建’ -> ...
- ubuntu 12.04下apache 配置家目录地址
apache2 最在搞前端相关的东西,上一次也记录了 Linux 下 LAMP环境的搭建,现在记录一下如果改变 apache2 的家目录地址该怎么做,改那个配置文件 修改配置文件 /etc/apach ...
- 树形dp - BNU 39572 Usoperanto
Usoperanto Problem's Link Mean: 给定n个单词,每个单词可以作为形容词来修饰其他单词. 如果当前单词Wi修饰Wj,那么这个修饰的代价是:Wi~Wj之间的单词的总长度. 你 ...
- 使用jQuery模拟Google的自动提示效果
注意: 1.本功能使用SqlServler2000中的示例数据库Northwind,请打SP3或SP4补丁:2.请下载jQuery组件,河西FTP中有下载:3.本功能实现类似Google自动提示的效果 ...
- JQuery操作表单相关使用总结
select下拉列表onChange事件之JQuery实现: JQuery: $(document).ready(function () { $("#selectMenu").bi ...
- 学习:在Eclipse中用TODO标签管理任务(Task)。
1.Windows->Perferences->Java->Compile->Task Tags,我们就可以自定义任务标签,Eclipse中可以支持HIgh,Normal,Lo ...
- AWS系列-创建AMI
AMI创建 在XEN中pv是半虚拟化,hvm是全虚拟化,pv只能用于linux内核的系统,效率更高,hvm可以虚拟所有常见操作系统(可以使用 windows),理论效率比pv略低,另外,hvm需要cp ...
- 剑指 offer set 26 不用加减乘除做加法
总结 1. Leetcode 上有一道题, 是不用乘除做乘法, 那道题算是背包问题的变形 2. 不用加减乘除, 还可以用移位操作 3. 将数字转成二进制格式, 然后运用二进制亦或, 移位运算解决 3. ...