一文带你理解RDD五大属性

RDD(Resilient Distributed Datasets)弹性的分布式数据集,它代表一个只读的、不可变、可分区,里面的元素可分布式并行计算的数据集。RDD是一个很抽象的概念,不易于理解,但是要想学好Spark,必须要掌握RDD,熟悉它的编程模型,这是学习Spark其他组件的基础。本文带大家理解RDD的五大特性。

一、RDD源码属性明细

源码文件RDD.scala中的RDD类有4个方法和一个属性,如下展示:

/** 通过子类实现给定分区的计算 */

@DeveloperApi

def compute(split: Partition, context: TaskContext): Iterator[T]

/**

* 通过子类实现,返回一个RDD分区列表,这个方法只被调用一次,它是安全的执行一次耗时计算

* 数组中的分区必须符合以下属性设置

*/

protected def getPartitions: Array[Partition]

/**

* 返回对父RDD的依赖列表,这个方法仅只被调用一次,它是安全的执行一次耗时计算

*/

protected def getDependencies: Seq[Dependency[_]] = deps

/**

* 可选的,指定优先位置,输入参数是spilt分片,输出结果是一组优先的节点位置

*/

protected def getPreferredLocations(split: Partition): Seq[String] = Nil

/**

* 可选的,通过子类实现,指定如何分区

*/

@transient

val partitioner: Option[Partitioner] = None

二、RDD五大特性详解

五大特性 之 分区列表

  1. Spark RDD是被分区的,每一个分区都会被一个计算任务(Task)处理。
  2. 分区数决定并行计算数量,RDD的并行度默认从父RDD传给子RDD。
  3. 默认情况下,一个HDFS上的数据分片就是一个Partition,RDD分片数决定了并行计算的力度,可以在创建RDD时指定RDD分片个数。
  4. 如果不指定分区数量,当RDD从集合创建时,则默认分区数量为该程序所分配到的资源的CPU核数(每个Core可以承载2~4个Partition),如果是从HDFS文件创建,默认为文件的Block数。

五大特性 之 计算函数

  1. 每一个分区都有一个计算函数(a function for computing each split)。
  2. 每个分区都会有计算函数,Spark的RDD的计算函数是以分片为基本单位的。
  3. 每个RDD都会实现compute函数,对具体的分片进行计算。RDD中的分片是并行的,所以是分布式并行计算。
  4. 有一点非常重要,就是由于RDD有前后依赖关系,遇到宽依赖关系,例如,遇到reduceBykey等宽依赖操作的算子,Spark将根据宽依赖划分Stage,Stage内部通过Pipeline操作,通过Block Manager获取相关的数据。
  5. 因为具体的split要从外界读数据,也要把具体的计算结果写入外界,所以用了一个管理器,具体的split都会映射成BlockManager的Block,而具体split会被函数处理,函数处理的具体形式是以任务的形式进行的。

五大特性 之 依赖列表

  1. 从上图可知rdd其中一大重要特性血缘依赖。依赖于其他RDD的列表(a list of dependencies on other RDDs)。
  2. RDD的依赖关系,由于RDD每次转换都会生成新的RDD,所以RDD会形成类似流水线的前后依赖关系,当然,宽依赖就不类似于流水线了,宽依赖后面的RDD具体的数据分片会依赖前面所有的RDD的所有的数据分片。
  3. 这时数据分片就不进行内存中的Pipeline,这时一般是跨机器的。
  4. 因为有前后的依赖关系,所以当有分区数据丢失的时候,Spark会通过依赖关系重新计算,算出丢失的数据,而不是对RDD所有的分区进行重新计算。
  5. RDD之间的依赖有两种:
  6. 窄依赖(Narrow Dependency)
  7. 宽依赖(Wide Dependency)
  8. RDD是Spark的核心数据结构
  9. 通过RDD的依赖关系形成调度关系。
  10. 通过对RDD的操作形成整个Spark程序。

五大特性 之 分区器

  1. key-value数据类型的RDD分区器(-Optionally,a Partitioner for key-value RDDS),控制分区策略和分区数。
  2. 每个key-value形式的RDD都有Partitioner属性,它决定了RDD如何分区。
  3. Partition的个数还决定每个Stage的Task个数。
  4. RDD的分片函数,想控制RDD的分片函数的时候可以分区(Partitioner)传入相关的参数,如HashPartitioner、RangePartitioner,它本身针对key-value的形式,如果不是key-value的形式,它就不会有具体的Partitioner。
  5. Partitioner本身决定了下一步会产生多少并行的分片,同时,它本身也决定了当前并行(parallelize)Shuffle输出的并行数据,从而使Spark具有能够控制数据在不同节点上分区的特性,用户可以自定义分区策略,如Hash分区等。
  6. Spark提供了“partitionBy”运算符,能通过集群对RDD进行数据再分配来创建一个新的RDD。

五大特性 之 优先位置

  1. 每个分区都有一个优先位置列表(-Optionally,a list of preferred locations to compute each split on)。
  2. 它会存储每个Partition的优先位置,对于一个HDFS文件来说,就是每个Partition块的位置。
  3. Spark的具体计算,具体分片前,它已经清楚地知道任务发生在什么节点上,也就是说,任务本身是计算层面的、代码层面的,代码发生运算之前已经知道它要运算的数据在什么地方,有具体节点的信息。

三、总结

RDD五大特性可以简单说明为:

  1. 分区列表(数据块列表,只保存数据位置,不保存具体地址)。
  2. 计算每个分片的函数(根据父RDD计算出子RDD)。
  3. RDD的依赖列表。
  4. 默认hash分区,可自定义分区器。
  5. 每一个分片的优先计算位置(preferred locations)列表,比如HDFS的block的所在位置应该是优先计算的位置。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值