Spark RDD

1. 什么是RDD?

RDD(弹性分布式数据集 – Resilient Distributed Dataset)是Spark的基本数据结构,它是在集群的不同节点上计算的不可变对象集合。RDD在内部进行逻辑分区,以便可以在集群的不同节点上进行计算。RDD具有容错能力,即它在故障情况下具有自恢复功能。

RDD可以被缓存和手动分区,当我们多次使用RDD时,缓存可以加速计算。手动分区对于正确平衡分区很重要,通常情况下,较小的分区允许更多的执行器更平均地分配RDD数据。

用户可以调用持久化方法(persist)来缓存RDD,默认情况下,Spark会将RDD保存在内存中,但如果内存不足,它可能会将RDD保存到磁盘中。用户还可以使用其他持久化策略,例如仅将RDD保存在磁盘中。

2. RDD的特点

2.1 内存计算

RDD提供了在内存中计算,它将中间结果存储在分布式内存(RAM)中,而不是磁盘上。

2.2 延迟计算

Spark中的所有转换都是延迟的,它们不会马上计算结果。相反,他们只记录应用于RDD的转换。

2.3 容错

RDD具有容错功能,“血统(lineage)”可以在故障时自动重建丢失的数据。

2.4 不变性

RDD是一个只读的分区记录集合。

2.5 分区

分区是RDD中并行性的基本单位,一个RDD可以包含多个分区,每个分区就是一个Dataset片段。可以通过对现有分区进行一些转换来创建新分区。

2.6 缓存

用户可以为重用的RDD选择缓存策略,例如:内存或磁盘。

2.7 粗粒度操作

操作应用于RDD中的所有元素。

2.8 位置感知性

RDD能够感知数据位置,Spark运行时使任务尽可能接近数据存放位置。 

3. RDD操作

RDD支持两种类型的操作:

转换(Transformation)和行动(Action)

3.1 转换(Transformation)

转换是将RDD作为输入并生成新RDD作为输出的函数,转换不改变输入RDD,通过转换函数生成新的RDD,例如:map()、filter()、reduceByKey()等。转换是延迟操作,当调用行动时创建新的RDD。某些转换可以是流水线处理,这是一种优化方法用于提高计算性能。每个转换操作都会生成一个新的RDD,所以RDD之间就会形成类似流水线的前后依赖关系,RDD有两种依赖:窄依赖和宽依赖,窄依赖可以在一个阶段(Stage)中进行流水线处理。

3.1.1 窄依赖

指每个父RDD的一个Partition最多被子RDD的一个Partition所使用,例如map、filter、union等操作都会产生窄依赖。

3.1.2 宽依赖

指一个父RDD的Partition会被多个子RDD的Partition所使用,例如groupByKey、reduceByKey、sortByKey等操作都会产生宽依赖。

3.2 行动(Action)

当RDD执行Action时候才会触发作业提交,执行相应的计算操作,例如:first()、take()、reduce()、collect()、count()、saveAsTextFile()、saveAsSequenceFile()等。

如何区别Transformation和Action:Transformation是从RDD产生新的RDD操作,Action是提交作业进行实际的计算。

4. RDD的限制

4.1 没有内置的优化引擎

在处理结构化数据时,RDD不能利用Spark的高级优化器,开发人员需要根据其属性来优化每个RDD。

4.2 处理结构化数据

与Dataframe不同,RDD不会推断数据的模式(Schema)。

4.3 性能限制

RDD是内存中的JVM对象,它涉及JVM垃圾收集/回收和对象序列化的开销,当数据增长时这些开销也将增长。

4.4 存储限制

当没有足够的内存来存储分区数据时,RDD会将该分区的数据存储在磁盘上。

Spark RDD
滚动到顶部