精华内容
下载资源
问答
  • 1.RDD 之间的依赖关系 导读 讨论什么是 RDD 之间的依赖关系 继而讨论 RDD 分区之间的关系 最后确定 RDD 之间的依赖关系分类 完善案例的逻辑关系图 什么是RDD之间的依赖关系? 什么是关系...

    1.RDD 之间的依赖关系

    导读

    1. 讨论什么是 RDD 之间的依赖关系

    2. 继而讨论 RDD 分区之间的关系

    3. 最后确定 RDD 之间的依赖关系分类

    4. 完善案例的逻辑关系图

    什么是 RDD 之间的依赖关系?

    20190519211533

    • 什么是关系(依赖关系) ?

      从算子视角上来看, splitRDD 通过 map 算子得到了 tupleRDD, 所以 splitRDD 和 tupleRDD 之间的关系是 map

      但是仅仅这样说, 会不够全面, 从细节上来看, RDD 只是数据和关于数据的计算, 而具体执行这种计算得出结果的是一个神秘的其它组件, 所以, 这两个 RDD 的关系可以表示为 splitRDD 的数据通过 map 操作, 被传入 tupleRDD, 这是它们之间更细化的关系

      但是 RDD 这个概念本身并不是数据容器, 数据真正应该存放的地方是 RDD 的分区, 所以如果把视角放在数据这一层面上的话, 直接讲这两个 RDD 之间有关系是不科学的, 应该从这两个 RDD 的分区之间的关系来讨论它们之间的关系

    • 那这些分区之间是什么关系?

      如果仅仅说 splitRDD 和 tupleRDD 之间的话, 那它们的分区之间就是一对一的关系

      但是 tupleRDD 到 reduceRDD 呢? tupleRDD 通过算子 reduceByKey 生成 reduceRDD, 而这个算子是一个 Shuffle 操作, Shuffle 操作的两个 RDD 的分区之间并不是一对一, reduceByKey 的一个分区对应 tupleRDD 的多个分区

    reduceByKey 算子会生成 ShuffledRDD

    reduceByKey 是由算子 combineByKey 来实现的, combineByKey 内部会创建 ShuffledRDD 返回, 具体的代码请大家通过 IDEA 来进行查看, 此处不再截图, 而整个 reduceByKey 操作大致如下过程

    20190520010402

    去掉两个 reducer 端的分区, 只留下一个的话, 如下

    20190520010518

    所以, 对于 reduceByKey 这个 Shuffle 操作来说, reducer 端的一个分区, 会从多个 mapper 端的分区拿取数据, 是一个多对一的关系

    至此为止, 出现了两种分区见的关系了, 一种是一对一, 一种是多对一

    整体上的流程图

    20190520011115

    2. RDD 之间的依赖关系详解

    导读

    上个小节通过例子演示了 RDD 的分区间的关系有两种形式

    • 一对一, 一般是直接转换

    • 多对一, 一般是 Shuffle

    本小节会说明如下问题:

    1. 如果分区间得关系是一对一或者多对一, 那么这种情况下的 RDD 之间的关系的正式命名是什么呢?

    2. RDD 之间的依赖关系, 具体有几种情况呢?

    窄依赖

    假如 rddB = rddA.transform(…​), 如果 rddB 中一个分区依赖 rddA 也就是其父 RDD 的少量分区, 这种 RDD 之间的依赖关系称之为窄依赖

    换句话说, 子 RDD 的每个分区依赖父 RDD 的少量个数的分区, 这种依赖关系称之为窄依赖

    20190520130939

    举个栗子

    val sc = ...
    
    val rddA = sc.parallelize(Seq(1, 2, 3))
    val rddB = sc.parallelize(Seq("a", "b"))
    
    /**
      * 运行结果: (1,a), (1,b), (2,a), (2,b), (3,a), (3,b)
      */
    rddA.cartesian(rddB).collect().foreach(println(_))
    • 上述代码的 cartesian 是求得两个集合的笛卡尔积

    • 上述代码的运行结果是 rddA 中每个元素和 rddB 中的所有元素结合, 最终的结果数量是两个 RDD 数量之和

    • rddC 有两个父 RDD, 分别为 rddA 和 rddB

    对于 cartesian 来说, 依赖关系如下

    20190520144103

    上述图形中清晰展示如下现象

    1. rddC 中的分区数量是两个父 RDD 的分区数量之乘积

    2. rddA 中每个分区对应 rddC 中的两个分区 (因为 rddB 中有两个分区), rddB 中的每个分区对应 rddC 中的三个分区 (因为 rddA 有三个分区)

    它们之间是窄依赖, 事实上在 cartesian 中也是 NarrowDependency 这个所有窄依赖的父类的唯一一次直接使用, 为什么呢?

    因为所有的分区之间是拷贝关系, 并不是 Shuffle 关系

    • rddC 中的每个分区并不是依赖多个父 RDD 中的多个分区

    • rddC 中每个分区的数量来自一个父 RDD 分区中的所有数据, 是一个 FullDependence, 所以数据可以直接从父 RDD 流动到子 RDD

    • 不存在一个父 RDD 中一部分数据分发过去, 另一部分分发给其它的 RDD

    宽依赖

     

    并没有所谓的宽依赖, 宽依赖应该称作为 ShuffleDependency

    在 ShuffleDependency 的类声明上如下写到

    Represents a dependency on the output of a shuffle stage.

    上面非常清楚的说道, 宽依赖就是 Shuffle 中的依赖关系, 换句话说, 只有 Shuffle 产生的地方才是宽依赖

    那么宽窄依赖的判断依据就非常简单明确了, 是否有 Shuffle ?

    举个 reduceByKey 的例子, rddB = rddA.reduceByKey( (curr, agg) ⇒ curr + agg ) 会产生如下的依赖关系

    20190520151040

    • rddB 的每个分区都几乎依赖 rddA 的所有分区

    • 对于 rddA 中的一个分区来说, 其将一部分分发给 rddB 的 p1, 另外一部分分发给 rddB 的 p2, 这不是数据流动, 而是分发

    如何分辨宽窄依赖 ?

    其实分辨宽窄依赖的本身就是在分辨父子 RDD 之间是否有 Shuffle, 大致有以下的方法

    • 如果是 Shuffle, 两个 RDD 的分区之间不是单纯的数据流动, 而是分发和复制

    • 一般 Shuffle 的子 RDD 的每个分区会依赖父 RDD 的多个分区

    但是这样判断其实不准确, 如果想分辨某个算子是否是窄依赖, 或者是否是宽依赖, 则还是要取决于具体的算子, 例如想看 cartesian 生成的是宽依赖还是窄依赖, 可以通过如下步骤

    1. 查看 map 算子生成的 RDD

      20190520155245

    2. 进去 RDD 查看 getDependence 方法

      20190520155314

    总结

    • RDD 的逻辑图本质上是对于计算过程的表达, 例如数据从哪来, 经历了哪些步骤的计算

    • 每一个步骤都对应一个 RDD, 因为数据处理的情况不同, RDD 之间的依赖关系又分为窄依赖和宽依赖 *

    3. 常见的窄依赖类型

    导读

    常见的窄依赖其实也是有分类的, 而且宽窄以来不太容易分辨, 所以通过本章, 帮助同学明确窄依赖的类型

    一对一窄依赖

    其实 RDD 中默认的是 OneToOneDependency, 后被不同的 RDD 子类指定为其它的依赖类型, 常见的一对一依赖是 map 算子所产生的依赖, 例如 rddB = rddA.map(…​)

    20190520160405

    • 每个分区之间一一对应, 所以叫做一对一窄依赖

    Range 窄依赖

    Range 窄依赖其实也是一对一窄依赖, 但是保留了中间的分隔信息, 可以通过某个分区获取其父分区, 目前只有一个算子生成这种窄依赖, 就是 union 算子, 例如 rddC = rddA.union(rddB)

    20190520161043

    • rddC 其实就是 rddA 拼接 rddB 生成的, 所以 rddC 的 p5 和 p6 就是 rddB 的 p1 和 p2

    • 所以需要有方式获取到 rddC 的 p5 其父分区是谁, 于是就需要记录一下边界, 其它部分和一对一窄依赖一样

    多对一窄依赖

    多对一窄依赖其图形和 Shuffle 依赖非常相似, 所以在遇到的时候, 要注意其 RDD 之间是否有 Shuffle 过程, 比较容易让人困惑, 常见的多对一依赖就是重分区算子 coalesce, 例如 rddB = rddA.coalesce(2, shuffle = false), 但同时也要注意, 如果 shuffle = true 那就是完全不同的情况了

    20190520161621

    • 因为没有 Shuffle, 所以这是一个窄依赖

    再谈宽窄依赖的区别

    宽窄依赖的区别非常重要, 因为涉及了一件非常重要的事情: 如何计算 RDD ?

    宽窄以来的核心区别是: 窄依赖的 RDD 可以放在一个 Task 中运行

    展开全文
  • 宽依赖与窄依赖

    2016-05-06 18:42:25
    宽依赖与窄依赖,很好用的PPT,对于spreak的宽依赖与窄依赖很清楚,分享给有用的朋友。
  • Spark 的join 什么时候是宽依赖什么时候是窄依赖 题目: 参考下面代码: 1.两个打印语句的结果是什么,对应的依赖是宽依赖还是窄依赖,为什么会是这个结果; 2.join 操作何时是宽依赖,何时是窄依赖; import org....

    Spark 的join 什么时候是宽依赖什么时候是窄依赖
    题目:
    参考下面代码:
    1.两个打印语句的结果是什么,对应的依赖是宽依赖还是窄依赖,为什么会是这个结果;
    2.join 操作何时是宽依赖,何时是窄依赖;

    
    import org.apache.spark.rdd.RDD
    import org.apache.spark.{HashPartitioner, SparkConf, SparkContext}
    object JoinDemo2 {
      def main(args: Array[String]): Unit = {
        val conf = new SparkConf().setAppName(this.getClass.getCanonicalName.init).setMaster("local[*]")
        val sc = new SparkContext(conf)
        sc.setLogLevel("WARN")
        val random = scala.util.Random
        val col1 = Range(1, 50).map(idx => (random.nextInt(10), s"user$idx"))
        val col2 = Array((0, "BJ"), (1, "SH"), (2, "GZ"), (3, "SZ"), (4, "TJ"), (5, "CQ"), (6, "HZ"), (7, "NJ"), (8, "WH"), (0,
          "CD"))
        val rdd1: RDD[(Int, String)] = sc.makeRDD(col1)
        val rdd2: RDD[(Int, String)] = sc.makeRDD(col2)
        val rdd3: RDD[(Int, (String, String))] = rdd1.join(rdd2)
        rdd3.count()
        println(rdd3.dependencies)
        val rdd4: RDD[(Int, (String, String))] = rdd1.partitionBy(new HashPartitioner(3)).join(rdd2.partitionBy(new
            HashPartitioner(3)))
        rdd4.count()
        println(rdd4.dependencies)
        Thread.sleep(10000000)
        sc.stop()
      }}
    

    回答:
    1.两个打印语句:List(org.apache.spark.OneToOneDependency@63acf8f6) List(org.apache.spark.OneToOneDependency@d9a498)
    在这里插入图片描述
    对应的依赖:
    rdd3对应的是宽依赖,rdd4对应的是窄依赖
    原因:
    1)参考webUI
    由DAG图可以看出,第一个join和之前的清晰划分成单独的Satge。可以看出这个是宽依赖。第二个join,partitionBy之后再进行join并没有单独划分成一个stage,由此可见是一个窄依赖。
    rdd3的join
    在这里插入图片描述
    rdd4的join
    在这里插入图片描述
    2)代码解析:
    a.首先是默认的join方法,这里使用了一个默认分区器

      /**
       * Return an RDD containing all pairs of elements with matching keys in `this` and `other`. Each
       * pair of elements will be returned as a (k, (v1, v2)) tuple, where (k, v1) is in `this` and
       * (k, v2) is in `other`. Performs a hash join across the cluster.
       */
      def join[W](other: RDD[(K, W)]): RDD[(K, (V, W))] = self.withScope {
        join(other, defaultPartitioner(self, other))
      }
    

    b.默认分区器,对于第一个join会返回一个以电脑core总数为分区数量的HashPartitioner.第二个join会返回我们设定的HashPartitioner(分区数目3)

      def defaultPartitioner(rdd: RDD[_], others: RDD[_]*): Partitioner = {
        val rdds = (Seq(rdd) ++ others)
        val hasPartitioner = rdds.filter(_.partitioner.exists(_.numPartitions > 0))
    
        val hasMaxPartitioner: Option[RDD[_]] = if (hasPartitioner.nonEmpty) {
          Some(hasPartitioner.maxBy(_.partitions.length))
        } else {
          None
        }
    
        val defaultNumPartitions = if (rdd.context.conf.contains("spark.default.parallelism")) {
          rdd.context.defaultParallelism
        } else {
          rdds.map(_.partitions.length).max
        }
    
        // If the existing max partitioner is an eligible one, or its partitions number is larger
        // than the default number of partitions, use the existing partitioner.
        if (hasMaxPartitioner.nonEmpty && (isEligiblePartitioner(hasMaxPartitioner.get, rdds) ||
            defaultNumPartitions < hasMaxPartitioner.get.getNumPartitions)) {
          hasMaxPartitioner.get.partitioner.get
        } else {
          new HashPartitioner(defaultNumPartitions)
        }
      }
    

    c.走到了实际执行的join方法,里面flatMapValues是一个窄依赖,所以说如果有宽依赖应该在cogroup算子中

      /**
       * Return an RDD containing all pairs of elements with matching keys in `this` and `other`. Each
       * pair of elements will be returned as a (k, (v1, v2)) tuple, where (k, v1) is in `this` and
       * (k, v2) is in `other`. Uses the given Partitioner to partition the output RDD.
       */
      def join[W](other: RDD[(K, W)], partitioner: Partitioner): RDD[(K, (V, W))] = self.withScope {
        this.cogroup(other, partitioner).flatMapValues( pair =>
          for (v <- pair._1.iterator; w <- pair._2.iterator) yield (v, w)
        )
      }
    

    d.进入cogroup方法中,核心是CoGroupedRDD,根据两个需要join的rdd和一个分区器。由于第一个join的时候,两个rdd都没有分区器,所以在这一步,两个rdd需要先根据传入的分区器进行一次shuffle,因此第一个join是宽依赖。第二个join此时已经分好区了,不需要再再进行shuffle了。所以第二个是窄依赖

      /**
       * For each key k in `this` or `other`, return a resulting RDD that contains a tuple with the
       * list of values for that key in `this` as well as `other`.
       */
      def cogroup[W](other: RDD[(K, W)], partitioner: Partitioner)
          : RDD[(K, (Iterable[V], Iterable[W]))] = self.withScope {
        if (partitioner.isInstanceOf[HashPartitioner] && keyClass.isArray) {
          throw new SparkException("HashPartitioner cannot partition array keys.")
        }
        val cg = new CoGroupedRDD[K](Seq(self, other), partitioner)
        cg.mapValues { case Array(vs, w1s) =>
          (vs.asInstanceOf[Iterable[V]], w1s.asInstanceOf[Iterable[W]])
        }
      }
    

    e.两个都打印出OneToOneDependency,是因为在CoGroupedRDD里面,getDependencies方法里面,如果rdd有partitioner就都会返回OneToOneDependency(rdd)。

      override def getDependencies: Seq[Dependency[_]] = {
        rdds.map { rdd: RDD[_] =>
          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.asInstanceOf[RDD[_ <: Product2[K, _]]], part, serializer)
          }
        }
      }
    
    1. join什么时候是宽依赖什么时候是窄依赖?
      由上述分析可以知道,如果需要join的两个表,本身已经有分区器,且分区的数目相同,此时,相同的key在同一个分区内。就是窄依赖。反之,如果两个需要join的表中没有分区器或者分区数量不同,在join的时候需要shuffle,那么就是宽依赖
    展开全文
  • Spark RDD 宽依赖&窄依赖1.窄依赖2.宽依赖:3.阶段的划分4.宽依赖和窄依赖的作用: 1.窄依赖 每一个父RDD的Partition最多被子RDD的一个Partition使用 (一对一的关系) 常见算子:map flatmap filter union sample...

    1.窄依赖

    每一个父RDD的Partition最多被子RDD的一个Partition使用 (一对一的关系)
    常见算子:map flatmap filter union sample 等等

    2.宽依赖:

    指的是多个子RDD的Partition会依赖同一个父RDD的Partition (一对多的关系)
    常见算子:groupByKey reduceByKey sortByKey join 等等

    在这里插入图片描述
    对于窄依赖的 RDD,可以以流水线的方式计算所有父分区,不会造成网络之间的数据混合。对于宽依赖的 RDD,则通常伴随着 Shuffle 操作,即首先需要计算好所有父分区数据,然后在节点之间进行 Shuffle。因此,在进行数据恢复时,窄依赖只需要根据父 RDD 分区重新计算丢失的分区即可,而且可以并行地在不同节点进行重新计算。而对于宽依赖而言,单个节点失效通常意味着重新计算过程会涉及多个父 RDD 分区,开销较大。此外,Spark 还提供了数据检查点和记录日志,用于持久化中间 RDD,从而使得在进行失败恢复时不需要追溯到最开始的阶段。在进行故障恢复时,Spark 会对数据检查点开销和重新计算 RDD 分区的开销进行比较,从而自动选择最优的恢复策略。

    3.阶段的划分

    Spark 通过分析各个 RDD 的依赖关系生成了 DAG ,再通过分析各个 RDD 中的分区之间的依赖关系来决定如何划分阶段,具体划分方法是:在 DAG 中进行反向解析,遇到宽依赖就断开,遇到窄依赖就把当前的 RDD 加入到当前的阶段中;将窄依赖尽量划分在同一个阶段中,可以实现流水线计算。例如在下图中,首先根据数据的读取、转化和行为等操作生成 DAG。然后在执行行为操作时,反向解析 DAG,由于从 A 到 B 的转换和从 B、F 到 G 的转换都属于宽依赖,则需要从在宽依赖处进行断开,从而划分为三个阶段。把一个 DAG 图划分成多个 “阶段” 以后,每个阶段都代表了一组关联的、相互之间没有 Shuffle 依赖关系的任务组成的任务集合。每个任务集合会被提交给任务调度器(TaskScheduler)进行处理,由任务调度器将任务分发给 Executor 运行。
    在这里插入图片描述
    DAG: 表示整个Spark的执行流程
    spark中划分stage通过宽依赖进行的,遇见宽依赖就切分,每个stage内部能多地包含一组具有窄依赖关系的转换,并将它们流水线并行化

    4.宽依赖和窄依赖的作用:

    1、stage划分
    2、容错(针对复杂业务逻辑,当执行到宽依赖的时候,进行适当的cache,担心任务异常结束,数据重跑)
    3、代码优化

    展开全文
  • 宽依赖和窄依赖 什么是依赖关系 当前的RDD和它的上级的RDD之间的一个描述. 一个应用下面有job,job下面有阶段,阶段怎么划分的,就是通过依赖关系划分的. 窄依赖 窄依赖表示每一个父RDD的Partition最多被子RDD的一个...
  • 2.宽依赖和窄依赖 3.宽依赖与窄依赖之间的对比 1.血统概念 利用内存加快数据加载,在众多的其它的In-Memory类数据库或Cache类系统中也有实现,Spark的主要区别在于它处理分布式运算环境下的数据容错性(节点实效/...
  • 宽依赖和窄依赖

    2019-03-19 15:43:49
    宽依赖与窄依赖 窄依赖是指父RDD的每个分区只被子RDD的一个分区所使用,子RDD分区通常对应常数个父RDD分区(O(1),与数据规模无关) 相应的,宽依赖是指父RDD的每个分区都可能被多个子RDD分区所使用,子RDD分区通常...
  • Spark中的窄依赖和宽依赖

    千次阅读 2018-05-24 16:56:03
    RDD之间的依赖关系又分为窄依赖和宽依赖,那到底什么是窄依赖什么是宽依赖呢?带着这个问题进入我们今天的学习。 2 窄依赖和宽依赖 2.1Lineage血统 Lineage保存了RDD的依赖关系。 RDD只支持粗粒度转换....
  • 其中,窄依赖的内容表达的不够全面,而宽依赖的部分容易让人产生误解。本文,我将用新的绘图带大家搞清楚究竟什么是宽依赖(ShuffleDependency),什么是窄依赖(NarrowDependency)。 为什么会有宽窄依赖? 我们...
  • RDD和它依赖的父RDD(s)的关系有两种不同的类型,即窄依赖(narrow dependency)和宽依赖(wide dependency)。 窄依赖: 窄依赖指的是每一个父RDD的Partition最多被子RDD的一个Partition使用 总结:窄依赖我们...
  • 窄依赖和宽依赖

    千次阅读 2018-07-23 14:07:55
    目录: 一.简介 二....三.stage划分 一....Spark中RDD的高效与DAG图...针对不同的转换函数,RDD之间的依赖关系分类窄依赖(narrow dependency)和宽依赖(wide dependency, 也称 shuffle dependency) 二.区别 窄依...
  • Spark中的宽依赖和窄依赖

    千次阅读 2018-08-08 17:35:56
    Spark中RDD的高效与DAG图有着莫大的关系, 在DAG调度中需要对计算过程划分Stage, ...和宽依赖(Wide Depencency,也称为Shuffle Depencency)。 窄依赖: 指父RDD的每个分区只被子RDD的一个分区所使用,子RD...
  • 一、转换算子转换算子: Transformation,懒...RDD[T],窄依赖 mapRDD[T] ->RDD[O], 窄依赖 flatMapRDD[T]–>RDD[[O]],一对多 ,窄依赖, mapToPairsample抽样算子 RDD[T]–>RDD[O],窄依赖 sortByRDD...
  • spark学习之宽依赖,窄依赖

    千次阅读 2019-04-24 19:27:42
    以子Rdd对父Rdd的依赖关系为纬度,1对1为窄,反之则! 二:宽窄之程序运行效率比较 例子1: 窄依赖在自己的节点中,逐个元素地执行map、然后filter操作,父RDD节点的计算不用等待其它父节点的计算结果。 ...
  • 宽依赖(Wide Depencency,也称为Shuffle Depencency)。 窄依赖: 指父RDD的每个分区只被子RDD的一个分区所使用,子RDD分区通常对应常数个父RDD分区(O(1),与数据规模无关) 宽依赖: 是指父RDD的每个分区都...
  • Spark的计算的基本单位一个一个的算子,其计算流程也是由一个个基本的算子构成的,这些算子之间的依赖关系可以分为宽依赖和窄依赖。 Spark是分布式计算,其数据也是分布式的,即所计算的数据可能分为好多个块。有些...
  • RDD的宽依赖和窄依赖

    2019-11-30 15:09:47
    1、RDD的宽依赖和窄依赖的区别 是否有shuffle操作,也叫洗牌操作 窄依赖: 一对一 或者 多对一 宽依赖: 一对多 窄依赖可以进行流水线优化,宽依赖不可以 优化:fork/join 机制 一个作业可以划分成多个阶段 ...
  • 内容简介一、窄依赖与宽依赖剖析二、窄依赖与宽依赖的区别三、窄依赖算子与宽依赖算子四、总结 一、窄依赖与宽依赖剖析 在之前的文章中曾对RDD进行剖析,详情看Spark学习之路(三):剖析RDD的概念及用三种方式创建...
  • 针对不同的转换函数,RDD之间的依赖关系分类窄依赖(narrow dependency)和宽依赖(wide dependency, 也称 shuffle dependency). 宽依赖与窄依赖  窄依赖是指父RDD的每个分区只被子RDD的一个分区所使用,子RD...
  • 宽依赖与窄依赖区别

    2019-04-17 16:30:00
    宽依赖往往对应着shuffle操作,需要在运行的过程中将同一个RDD分区传入到不同的RDD分区中,中间可能涉及到多个节点之间数据的传输,而窄依赖的每个父RDD分区通常只会传入到另一个子RDD分区,通常在一个节点内完成。...
  • 宽依赖和窄依赖的区别 参考: https://blog.csdn.net/u013384984/article/details/80963455 总结一下: 窄依赖:父RDD中,每个分区内的数据,都只会被子RDD中特定的分区所消费,为窄依赖: **宽依赖:**父RDD中,...
  • 宽依赖:一个父节点对应多个子节点 窄依赖:一个父节点对应一个子节点,或多个父节点对应一个子节点 我的理解 宽依赖:一个父节点会被拆分开对应多个子节点 窄依赖:一个父节点不会被拆分,会完整的对应下一个...
  • spark中的宽依赖,与窄依赖的区别 在一个程序里面产生宽依赖和窄依赖的RDD是分父RDD和子RDD的,其中父RDD和子RDD是相对而言, 相邻两个RDD处理之前是父RDD,处理之后就是子rdd,具体你用的什么算子产生没有产生shuffle...
  • 宽依赖对应的是shuffle操作,需要在运行时将同一个父RDD的分区传入到不同的子RDD分区中,不同的分区可能位于不同的节点,就可能涉及多个节点间数据传输 当RDD分区丢失时,Spark会对数据进行重新计算,对于窄依赖只需...
  • 开门见山,本文就针对一个点,谈谈Spark中的宽依赖和窄依赖,这是Spark计算引擎划分Stage的根源所在,遇到宽依赖,则划分为多个stage,针对每个Stage,提交一个TaskSet: 上图:一张网上的图: 基于此图,分析下...
  • 宽依赖、窄依赖与shuffle

    千次阅读 2018-12-03 23:45:23
    概念上来说  Shuffle的含义就是洗牌,将数据打散,父RDD一个分区中的数据如果给了子RDD的多...宽依赖:存在shuffle  也许大家看了上面的说法只是有个初步的印象,下面我将以join为例进行讲解,相信大家看了这个...
  • RDD: rdd是是不可更改的,分区的,可并行执行的分布式数据集。partition是rdd的重要概念也可以说rdd是一组分区数据组成的,而不同的分区可以发送到不同的节点上并行执行,rdd的概念造是数据能够并行执行的基础。...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 83,097
精华内容 33,238
关键字:

宽依赖