• RDD 依赖关系


    1、血缘关系&依赖关系

    RDD只支持粗粒度转换,即在大量记录上执行的单个操作。将创建RDD的一系列Lineage(血统)记录下来,以便恢复丢失的分区。RDD的Lineage会记录RDD的元数据信息和转换行为,当该RDD的部分分区数据丢失时,它可以根据这些信息来重新运算和恢复丢失的数据分区。
    血缘关系

     依赖关系

    代码实现

    object Spark01_lineage {
      def main(args: Array[String]): Unit = {
        //创建 配置对象
        val conf: SparkConf = new SparkConf().setAppName("wordcount").setMaster("local[*]")
        //配置上下文对象
        var sc: SparkContext = new SparkContext(conf)
        val rdd: RDD[String] = sc.makeRDD(List("hello spark", "flink", "hello", "word hello"))
        //rdd 血缘关系
        println(rdd.toDebugString)
        println(rdd.dependencies)
        println("**************************************")
        val flatMap: RDD[String] = rdd.flatMap(_.split(" "))
        println(flatMap.toDebugString)
        println(flatMap.dependencies)
        println("**************************************")
        val map: RDD[(String, Int)] = flatMap.map((_, 1))
        println(map.toDebugString)
        println(map.dependencies)
        println("**************************************")
        val resRDD: RDD[(String, Int)] = map.reduceByKey(_ + _)
        println(resRDD.toDebugString)
        println(resRDD.dependencies)
        resRDD.collect().foreach(println)
        //关闭
        sc.stop()
      }
    }
    

    血缘关系

    (4) ParallelCollectionRDD[0] at makeRDD at Spark01_lineage.scala:15 []
    **************************************
    (4) MapPartitionsRDD[1] at flatMap at Spark01_lineage.scala:20 []
     |  ParallelCollectionRDD[0] at makeRDD at Spark01_lineage.scala:15 []
     **************************************
     (4) MapPartitionsRDD[2] at map at Spark01_lineage.scala:24 []
     |  MapPartitionsRDD[1] at flatMap at Spark01_lineage.scala:20 []
     |  ParallelCollectionRDD[0] at makeRDD at Spark01_lineage.scala:15 []
     **************************************
    (4) ShuffledRDD[3] at reduceByKey at Spark01_lineage.scala:28 []
     +-(4) MapPartitionsRDD[2] at map at Spark01_lineage.scala:24 []
        |  MapPartitionsRDD[1] at flatMap at Spark01_lineage.scala:20 []
        |  ParallelCollectionRDD[0] at makeRDD at Spark01_lineage.scala:15 []
    血缘关系说明
    (4) ParallelCollectionRDD[0] at makeRDD at Spark01_lineage.scala:15 []
    //第15行通过集合创建RDD,makeRDD 是 ParallelCollectionRDD 的封装
    **************************************
    (4) MapPartitionsRDD[1] at flatMap at Spark01_lineage.scala:20 []
       //第20行通过flatMap创建RDD,flatMap 是 MapPartitionsRDD的封装
     |  ParallelCollectionRDD[0] at makeRDD at Spark01_lineage.scala:15 []
     **************************************
     (4) MapPartitionsRDD[2] at map at Spark01_lineage.scala:24 []
     //第24行map转换结构,map 也是 MapPartitionsRDD的封装
     |  MapPartitionsRDD[1] at flatMap at Spark01_lineage.scala:20 []
     |  ParallelCollectionRDD[0] at makeRDD at Spark01_lineage.scala:15 []
     **************************************
    (4) ShuffledRDD[3] at reduceByKey at Spark01_lineage.scala:28 []
    //28行执行了 reduceByKey ,存在shuffle,单独列了一行
     +-(4) MapPartitionsRDD[2] at map at Spark01_lineage.scala:24 []
        |  MapPartitionsRDD[1] at flatMap at Spark01_lineage.scala:20 []
        |  ParallelCollectionRDD[0] at makeRDD at Spark01_lineage.scala:15 []
    整个RDD的血缘关系是从下至上的,输出的依赖关系 
    List()
    List(org.apache.spark.OneToOneDependency@27d57a2c)
    List(org.apache.spark.OneToOneDependency@59532566)
    List(org.apache.spark.ShuffleDependency@5524b72f)
    全局搜索(ctrl+n)org.apache.spark.OneToOneDependency
    @DeveloperApi
    class OneToOneDependency[T](rdd: RDD[T]) extends NarrowDependency[T](rdd) {
      override def getParents(partitionId: Int): List[Int] = List(partitionId)
    }
    
    NarrowDependency 即窄依赖,查看当前类名是
    @DeveloperApi
    abstract class Dependency[T] extends Serializable {
      def rdd: RDD[T]
    }
    

    按 ctrl + h 查看实现方法

     

    注意:要想理解RDD是如何工作的,最重要的就是理解Transformations。

    RDD 之间的关系可以从两个维度来理解: 一个是 RDD 是从哪些 RDD 转换而来, 也就是 RDD 的 parent RDD(s)是什么; 另一个就是 RDD 依赖于 parent RDD(s)的哪些 Partition(s). 这种关系就是 RDD 之间的依赖.
    RDD和它依赖的父RDD(s)的关系有两种不同的类型,即窄依赖(narrow dependency)和宽依赖(wide dependency)

    2、宽/窄依赖

    窄依赖 窄依赖表示每一个父RDD的Partition最多被子RDD的一个Partition使用,窄依赖我们形象的比喻为独生子女。

     

    宽依赖 宽依赖表示同一个父RDD的Partition被多个子RDD的Partition依赖,会引起Shuffle,总结:宽依赖我们形象的比喻为超生。

     

    具有宽依赖的 transformations 包括: sort, reduceByKey, groupByKey, join, 和调用rePartition函数的任何操作.宽依赖对 Spark 去评估一个 transformations 有更加重要的影响, 比如对性能的影响.

    3、Spark 中Job 调度

    一个Spark应用包含一个驱动进程(driver process,在这个进程中写Spark的逻辑代码)和多个执行器进程(executor process,跨越集群中的多个节点)。Spark 程序自己是运行在驱动节点, 然后发送指令到执行器节点。一个Spark集群可以同时运行多个Spark应用, 这些应用是由集群管理器(cluster manager)来调度。Spark应用可以并发的运行多个job, job对应着给定的应用内的在RDD上的每个 action操作。Spark应用:一个Spark应用可以包含多个Spark job, Spark job是在驱动程序中由SparkContext 来定义的。当启动一个 SparkContext 的时候, 就开启了一个 Spark 应用。 一个驱动程序被启动了, 多个执行器在集群中的多个工作节点(worker nodes)也被启动了。 一个执行器就是一个 JVM, 一个执行器不能跨越多个节点, 但是一个节点可以包括多个执行器。一个 RDD 会跨多个执行器被并行计算. 每个执行器可以有这个 RDD 的多个分区, 但是一个分区不能跨越多个执行器.

    Spark Job 的划分:由于Spark的懒执行, 在驱动程序调用一个action之前, Spark 应用不会做任何事情,针对每个action,Spark 调度器就创建一个执行图(execution graph)和启动一个 Spark job。每个 job 由多个stages 组成, 这些 stages 就是实现最终的 RDD 所需的数据转换的步骤。一个宽依赖划分一个stage。每个 stage 由多个 tasks 来组成, 这些 tasks 就表示每个并行计算, 并且会在多个执行器上执行。

  • 相关阅读:
    两个单向链表的第一个公共节点
    c字符输出
    堆排序
    归并排序
    LR中,URL -based script与HTML -based script区别
    loadrunner文本检查点
    Loadrunner集合点Rendezvous知识
    连接池(Connection Pool)技术
    lucene 查询 (转载)
    Lucene + Hadoop 分布式搜索运行框架 Nut 1.0a9转自http://www.linuxidc.com/Linux/2012-02/53113.htm
  • 原文地址:https://www.cnblogs.com/wdh01/p/16319901.html
Copyright © 2020-2023  润新知