为什么会产生RDD及其作用

1为什么会产生RDD

(1) 传统的MapReduce虽然具有自动容错、平衡负载和可拓展性的优点,但是其最大缺点是采用非循环式的数据流模型,使得在迭代计算式要进行大量的磁盘IO操作。RDD正是解决这一缺点的抽象方法。
(2) RDD是Spark提供的最重要的抽象的概念,它是一种有容错机制的特殊集合,可以分布在集群的节点上,以函数式编操作集合的方式,进行各种并行操作。可以将RDD理解为一个具有容错机制的特殊集合,它提供了一种只读、只能有已存在的RDD变换而来的共享内存,然后将所有数据都加载到内存中,方便进行多次重用。
    

a. 他是分布式的,可以分布在多台机器上,进行计算。
b. 他是弹性的,计算过程中内存不够时它会和磁盘进行数据交换。
c. 这些限制可以极大的降低自动容错开销
d. 实质是一种更为通用的迭代并行计算框架,用户可以显示的控制计算的中间结果,
然后将其自由运用于之后的计算。

(3) RDD的容错机制实现分布式数据集容错方法有两种:数据检查点和记录更新RDD

  采用记录更新的方式:记录所有更新点的成本很高。所以,RDD只支持粗 颗粒变换,即只记录单个块上执行的单个操作,然后创建某个RDD的变换序列(血统)存储下来;变换序列指,每个RDD都包含了他是如何由其他RDD变换过来的以及如何重建某一块数据的信息。因此RDD的容错机制又称“血统”容错。 要实现这种“血统”容错机制,最大的难题就是如何表达父RDD和子RDD之间的依赖关系。实际上依赖关系可以分两种,窄依赖和宽依赖:窄依赖:子RDD中的每个数据块只依赖于父RDD中对应的有限个固定的数据块;宽依赖:子RDD中的一个数据块可以依赖于父RDD中的所有数据块。(后面会详细介绍两种依赖)

(4)RDD内部的设计每个RDD都需要包含以下四个部分:

a. 源数据分割后的数据块,源代码中的splits变量
b. 关于“血统”的信息,源码中的dependencies变量
c. 一个计算函数(该RDD如何通过父RDD计算得到),
源码中的iterator(split)和compute函数
d. 一些关于如何分块和数据存放位置的元信息,
如源码中的partitioner和preferredLocations
  • 源码:
 /**
   * 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 }`
   */
//只计算一次  
  protected def getPartitions: Array[Partition]  

/**
   * :: DeveloperApi ::
   * Implemented by subclasses to compute a given partition.
   */
  //对一个分片进行计算,得出一个可遍历的结果
  def compute(split: Partition, context: TaskContext): Iterator[T]

/**
   * 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.
  */
  //只计算一次,计算RDD对父RDD的依赖
  protected def getDependencies: Seq[Dependency[_]] = deps

/** 
Optionally overridden by subclasses to specify how they are partitioned. 
*/
  //可选的,分区的方法,针对第4点,类似于mapreduce当中的Paritioner接口,控制key分到哪个reduce
  @transient val partitioner: Option[Partitioner] = None

/**
   * Optionally overridden by subclasses to specify placement preferences.
   */
  //可选的,指定优先位置,输入参数是split分片,输出结果是一组优先的节点位置
  protected def getPreferredLocations(split: Partition): Seq[String] = Nil
2 RDD在Spark中的地位及作用

(1)为什么会有Spark?因为传统的并行计算模型无法有效的解决迭代计算(iterative)和交互式计算(interactive);而Spark的使命便是解决这两个问题,这也是他存在的价值和理由。

(2)Spark如何解决迭代计算?其主要实现思想就是RDD,把所有计算的数据保存在分布式的内存中。迭代计算通常情况下都是对同一个数据集做反复的迭代计算,数据在内存中将大大提升IO操作。这也是Spark涉及的核心:内存计算。

(3)Spark如何实现交互式计算?因为Spark是用scala语言实现的,Spark和scala能够紧密的集成,所以Spark可以完美的运用scala的解释器,使得其中的scala可以向操作本地集合对象一样轻松操作分布式数据集。

(4)Spark和RDD的关系?可以理解为:RDD是一种具有容错性基于内存的集群计算抽象方法,Spark则是这个抽象方法的实现。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值