[Spark]-源码解析-RDD的五大特征体现

1.概述

  众所周知,RDD有五大特性.

    i). A list of partitions

        RDD是由多个分区(partition)组成的一个集合

    ii). A function for computing each split

        对RDD的每一个计算,等于对这个RDD的每一个分区执行一个计算

    iii). A list of dependencies on other RDDs

      每一个RDD都会记录它的父RDD的依赖(如果是第一个,则会是对数据源的依赖)

    iv). Optionally, a Partitioner for key-value RDDs (e.g. to say that the RDD is hash-partitioned)

       如果RDD里存放的是Key-Value的形式.则可以传入一个自定义的分区函数进行分区(比如自定义按Key分区,则会将不同RDD的相同Key都集中在一个Partition中)

    v). Optionally, a list of preferred locations to compute each split on (e.g. block locations for an HDFS file)

      计算就近原则.计算会尽可能的放入split所在的节点中

  接下来从源码角度,体现出这五大特性

2.这耳熟能详的五大特性的真正出处

  

3.五大特性的源码体现如下:

/**
   * Implemented by subclasses to compute a given partition.
   *
   * 可以看出compute是所有RDD子类都必须实现的 用于计算给定的分区的 抽象方法.. 
   *     注意这里 compute的入参是 split: Partition 因此所有的计算都是以Partition为基准的(特性2)
   */
  @DeveloperApi
  def compute(split: Partition, context: TaskContext): Iterator[T]

  /**
   * Implemented by subclasses to return the set of partitions in this RDD. This method will only
   * be called once, so it is safe to implement a time-consuming computation in it.
   *
   * The partitions in this array must satisfy the following property:
   *   `rdd.partitions.zipWithIndex.forall { case (partition, index) => partition.index == index }`
   *
   * 可以看出 getPartitions 是所有RDD子类都必须实现的. 用于返回RDD的分区集 
   *      这也说明 RDD 本身是由 Partition(分区) 组成的 (特性1)
   *    另外:这个方法只会被调用一次. 这说明了RDD的一个隐藏特性: RDD是不可变的
   */
  protected def getPartitions: Array[Partition]

  /**
   * Implemented by subclasses to return how this RDD depends on parent RDDs. This method will only
   * be called once, so it is safe to implement a time-consuming computation in it.
   *
   * getDependencies 获取这个RDD的依赖关系. 注意: deps 是由RDD的构造传入的.
   *    这说明 RDD必然会记录它依赖(构造必须传入) (特性3)
   */
  protected def getDependencies: Seq[Dependency[_]] = deps

  /**
   * Optionally overridden by subclasses to specify placement preferences.
   * 
   * getPreferredLocations 获取这个RDD存储路径. Seq[String] 因为有副本概念.Seq(0)就是首选地址 (特性5)
   */
  protected def getPreferredLocations(split: Partition): Seq[String] = Nil

  /** Optionally overridden by subclasses to specify how they are partitioned. 
  * 
  * partitioner 分区函数. 如果需要就可以自定义分区算法覆盖分区函数 (特性4)
  */
  @transient val partitioner: Option[Partitioner] = None

    

原文地址:https://www.cnblogs.com/NightPxy/p/9324532.html