Spark RDD(弹性分布式数据集)

1. RDD

1.1 RDD 是什么

RDD(Resilient Distributed Dataset):弹性分布式数据集,是 Spark 对数据集的抽象,代表一个只读、不可变、可分区、其中元素可进行并行计算的集合,并且是可跨越集群节点进行并行操作的有容错机制的集合。

RDD 是通过 Hadoop 文件系统(HDFS)中文件或者驱动程序中现有的 Scala 集合开始,然后对其进行转换来创建的。

1.2 RDD 特性

*  - A list of partitions
// RDD 是一个包含多个分区的列表
*  - A function for computing each split
// RDD 会在每个分片(分区)上单独启动一个线程,并行完成函数操作
*  - A list of dependencies on other RDDs
// RDDs 会存储其他 RDD 的依赖关系
*  - Optionally, a Partitioner for key-value RDDs (e.g. to say that the RDD is hash-partitioned)
// 以二元组作为泛型的 RDD,可以设置分区器,按照 key 对数据进行分组或者聚合操作
*  - Optionally, a list of preferred locations to compute each split on (e.g. block locations for an HDFS file)
// RDD 默认从最优位置读取原始文件

abstract class RDD[T: ClassTag](..)

1.2.1 不可变(只读)

由于 RDD 出错时,需要重新从上游 RDD 中读取数据,并进行重新计算,所以每次转换操作,都不会改变原有的 RDD,而是只读取原有的 RDD 中的数据,将计算结果写入到新的 RDD 中。

1.2.2 弹性

随时调整并发度:

RDD 中的分区数,对应 Spark 程序中的(Task)线程数(并发度),可以在每一步计算中,随时调整 RDD 的分区数,来改变程序的并发度,从而优化任务流程。

任务出错时可重试:

Spark 任务计算出错时,会首先向上游 RDD 重新读取数据,并进行重试(4次),如果失败,会继续向上;如果最终还是失败,会将当前任务转移到另一台 worker 中重新尝试。

1.2.3 懒加载(懒执行):

RDD 只有在调用 action 算子时才会开始真正执行计算任务,如果整个 RDD 依赖列表中没有 action 操作,RDD 仅仅编译并记录依赖关系,而不执行。

1.2.4 依赖

RDDs 通过操作算子进行转换,转换得到的新 RDD 包含了从其他 RDDs 衍生所必需的信息,RDDs之间维护着这种依赖关系。

依赖有两种:

  • 窄依赖:一一对应
  • 宽依赖:多对多

1.2.5 缓存

如果应用程序中多次使用一个 RDD,则会将 RDD 缓存起来,该 RDD 只有在第一次计算的时候会根据依赖关系得到分区的数据,在后续其他地方使用该 RDD 时,会从缓存处取出而不会再根据依赖关系计算。

设置缓存

将 rdd 设置缓存:

val sc = new SparkContext()
val rdd:RDD[String] = sc.textFile("Harry.txt")
rdd.cache()

进入到该方法的源码中,可以看到,cache 使用的是空参的 persist 方法:

// 使用默认的存储级别(' MEMORY_ONLY ')持久化这个RDD。
def cache(): this.type = persist()

def persist(): this.type = persist(StorageLevel.MEMORY_ONLY)

由此可见设置缓存级别的是 persist() 方法!该方法的源码如下:

image-20211209171810750

缓存级别

StorageLevel 类的伴生对象中,可以找到所有的缓存级别:

image-20211209171925235

缓存级别描述
MEMORY_ONLY默认的缓存级别,将 RDD 作为 Java 的反序列化对象(原数据)存储在 JVM 中,提供下一次或多次使用。如果 RDD 不适合缓存,则每次使用时都要重新计算。
MEMORY_AND_DISK当内存溢出时,会将缓存的数据溢写到磁盘中。(优先使用内存)
MEMORY_ONLY_SER将 RDD 作为 Java 的序列化对象存储在 JVM 中,序列化对象更节省空间,但需要消耗 CPU 资源。
MEMORY_AND_DISK_SER当内存溢出时,会将缓存的序列化对象溢写到磁盘中。
DISK_ONLYRDD 仅存储在磁盘中
MEMORY_ONLY_2, MEMORY_AND_DISK_2, etc.将在两个集群节点上进行缓存。
OFF_HEAP (experimental)类似于 MEMORY_ONLY_SER,但是会将 RDD 缓存在堆外内存。

非堆存储技术:将 RDD 中的对象存储在非 JVM 堆内存。

原因是 JVM HEAP 中的对象在回收(GC)时,需要暂停任务线程,会导致整体效率降低!

1.2.6 CheckPoint

RDD 之间的依赖关系提供了容错机制,当 RDD 的某个分区的数据计算失败时会通过依赖关系进行重建,但对于依赖关系过长的程序,一旦后续过程中出错,则会影响到性能。CheckPoint 机制实现将数据持久化到磁盘中,则阻断了依赖关系,后续的过程可从磁盘中获取该检查点的数据。

如果为 RDD 设置了检查点,会创建一个二进制文件,并存储在 checkpoint 目录中,该目录使用 SparkContext.setCheckpointDir() 方法设置。在使用 checkpoint 的过程中,RDD 的所有依赖信息将被清除。checkpoint 操作仅在 Action 操作时才会触发。

checkpoint 在任务结束之前,可以代替 DISK 级别的缓存!

设置 CheckPoint
val sc = new SparkContext()

val rdd:RDD[String] = sc.textFile("Harry.txt")

rdd.checkpoint()

checkpoint 源码:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZxZkEIz6-1639044849840)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20211209180355774.png)]

1.3 RDD 操作

1、创建 RDD

2、RDD 转换

3、RDD Action

4、RDD 缓存

 


❤️ END ❤️
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

JOEL-T99

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值