分享
Spark中的narrow/wide dependency如何理解,有什么作用?
我在RDD的论文中看到他们的定义是这样的”narrow dependencies, where eachpartition of the parent RDD is used by at most one partitionof the child RDD, wide dependencies, where multiplechild partitions may depend on it”我的理解是narrow就是独生子女,一个父亲只有一个孩子;wide是一个父亲多个孩子。但是我感觉这个定义与论文中区分这两种dependency的作用是矛盾的:“First, narrowdependencies allow for pipelined execution on one clusternode, which can compute all the parent partitions. Forexample, one can apply a map followed by a filter on anelement-by-element basis. In contrast, wide dependenciesrequire data from all parent partitions to be availableand to be shuffled across the nodes using a MapReducelikeoperation. Second, recovery after a node failure ismore efficient with a narrow dependency, as only the lostparent partitions need to be recomputed, and they can berecomputed in parallel on different nodes. In contrast, ina lineage graph with wide dependencies, a single failednode might cause the loss of some partition from all theancestors of an RDD, requiring a complete re-execution.”narrow的第一个作用,我的理解是可以不用等上一次操作全部做完,每完成一条记录就可以进行下次操作,如map产生一条新纪录马上就做filter,但是对于wide,为什么不能这样做呢?另外,union是narrow操作,对两个分区做合并不需要shuffle吗,为什么只有wide操作才需要shuffle?对于narrow的第二个作用,两种dependency丢失单个分区会分别导致哪些其他分区也丢失呢?
回复 ( 6 )
如图:
(图片来源:)
我们知道RDD就是一个不可变的带分区的记录集合,Spark提供了RDD上的两类操作,转换和动作。转换是用来定义一个新的RDD,包括map, flatMap, filter, union, sample, join, groupByKey, cogroup, ReduceByKey, cros, sortByKey, mapValues等,动作是返回一个结果,包括collect, reduce, count, save, lookupKey。
首先要注意一点,就是分区,那么:
参见: 与 Hadoop 对比,如何看待 Spark 技术? – 用心阁的回答
楼上答案很好。。。我想能解答楼主疑问了。。。我是来讨论的。。。
如果把wide split的定义改为child partition depends on multiple parents which are not guaranteed to exist on the same node的话,解释就变得非常简单了——multiple parents的数据必须shuffle到同一个node上才可以算child。。。这是楼上说的2号情况。。。我一向也是这么理解的。。。
不过感谢题主把原论文中关于这个概念的原话贴出来,给了我一个重新思考这个问题的机会。。。
我发现真的很神奇哦。。。spark真的是按照论文里那么设计的而不是按照我以往的理解。。。
试想,如果我们搞一个localSplit的操作,把一个partition分成同一个node上的多个partitions. 这是一个multiple children depend on one parent的wide dependency情况,但是正如题主说的,好像也没有什么不可以的。。。反正数据都在同一个node上,想怎么搞还不是随便。。。
然而spark就真的没这类transformation!!!真的没有。。。coalesce只能减少partition数。。。repartition用的是shuffle的办法。。。。凡是可能改变partition数的transformation(除了coalesce)貌似都需要shuffle。。。
当然可以想象对一个partition执行某个计算得到的结果不容易同时存入两个不同的partitions, 也可以理解localSplit这类操作好像也不是非常有意义,但是依然觉得这是一个可以解决的问题。。。
这个设定究竟是出于某些我没想到的固有限制,还是仅仅是spark就想这么设计?没想明白。。。
@用心阁能解答一下吗。。。
其中一个作用 可用于区分stage 方便stage内优化
其二 真的就是数据行为特点 需要多依赖
楼上有人画了Stage的划分,但是似乎没有正对性地回答楼主的问题。
在这里说一下我的理解,希望可以和大家讨论。
0. 首先,关于楼主的例子。
“独生子女”、“父亲”的概念应该对应的都是RDD里的partition的概念。那么narrow dependency 的理解,根据论文里的定义应该是,每个父亲至多只有一个孩子,此时,也可以是多个父亲对应一个孩子。而wide dependency里,多个孩子会依赖同一个父亲,也就是child RDD里的partition会依赖于parent(s)RDD里的多个partitions
我之前从集合映射的概念去理解。如果从parent RDD里的partition 到child RDD的partition是一对一或者多对一的,就是narrow dependency;若为多对多或者一对多的,则是wide dependency
1. 关于楼主的第一个问题,举个例子:
我的疑问和题主一样,包括为什么宽依赖不能流水线 (pipeline)优化?
比如cogroup是一个字分区有有限个父分区,多个依赖的数据不还是要fetch过来
@用心阁 已经给出了专业答案。
按楼主自己粗糙的说法,“narrow就是独生子女,一个父亲只有一个孩子;wide是一个父亲多个孩子”,wide更像是多个父亲一(多)个孩子….O(∩_∩)O哈哈~