3.5 RDD持久化机制

本文详细介绍了Spark中的RDD持久化机制,包括持久化的必要性、案例演示持久化操作、存储级别选择以及如何设置存储级别。通过持久化可以避免重复计算,提高效率。RDD的存储级别包括MEMORY_ONLY、MEMORY_AND_DISK等,选择存储级别时需要权衡内存使用率和CPU效率。此外,还展示了如何在代码中设置存储级别以及如何利用Spark WebUI查看缓存信息。

一、RDD持久化
(一)引入持久化的必要性
Spark中的RDD是懒加载的,只有当遇到行动算子时才会从头计算所有RDD,而且当同一个RDD被多次使用时,每次都需要重新计算一遍,这样会严重增加消耗。为了避免重复计算同一个RDD,可以将RDD进行持久化。
Spark中重要的功能之一是可以将某个RDD中的数据保存到内存或者磁盘中,每次需要对这个RDD进行算子操作时,可以直接从内存或磁盘中取出该RDD的持久化数据,而不需要从头计算才能得到这个RDD。
(二)案例演示持久化操作
1、RDD的依赖关系图
读取文件,进行一系列操作,有多个RDD,如下图所示。

2、不采用持久化操作
在上图中,对RDD3进行了两次算子操作,分别生成了RDD4和RDD5。若RDD3没有持久化保存,则每次对RDD3进行操作时都需要从textFile()开始计算,将文件数据转化为RDD1,再转化为RDD2,最终才得到RDD3。

查看要操作的HDFS文件

以集群模式启动Spark Shell

按照图示进行操作,得RDD4和RDD5

查看RDD4内容,会从RDD1到RDD2到RDD3到RDD4跑一趟

显示RDD5内容,也会从RDD1到RDD2到RDD3到RDD5跑一趟

3、采用持久化操作
可以在RDD上使用persist()或cache()方法来标记要持久化的RDD(cache()方法实际上底层调用的是persist()方法)。在第一次行动操作时将对数据进行计算,并缓存在节点的内存中。Spark的缓存是容错的:如果缓存的RDD的任何分区丢失,Spark就会按照该RDD原来的转换过程自动重新计算并缓存。

计算到RDD3时,标记持久化

计算RDD4,就是基于RDD3缓存的数据开始计算,不用从头到尾跑一趟

计算RDD5,就是基于RDD3缓存的数据开始计算,不用从头到尾跑一趟

二、存储级别
(一)持久化方法的参数
利用RDD的persist()方法实现持久化,向persist()方法中传入一个StorageLevel对象指定存储级别。每个持久化的RDD都可以使

RDD持久化是Spark非常重要的一个功能特性,下面从原理、方法及应用场景三方面进行介绍: - **原理**:Spark可将RDD持久化到内存中,当对RDD执行持久化操作时,每个节点会把自己操作的RDD的partition持久化到内存里,在后续对该RDD的反复使用中,直接使用内存缓存的partition。这样就在针对一个RDD反复执行多个操作的场景下,只需对RDD计算一次,后续直接使用该RDD,无需反复计算。而且Spark的持久化机制自动容错,若持久化RDD的任何partition丢失,Spark会自动通过其源RDD,使用transformation操作重新计算该partition。此外,Spark自己也会在shuffle操作时进行数据的持久化,像写入磁盘,这样能在节点失败时避免重新计算整个过程[^2][^3]。 - **方法**:要持久化一个RDD,可调用其cache()或者persist()方法。在该RDD第一次被计算出来时,就会直接缓存在每个节点中。cache()是persist()的简化方式,cache()底层调用的是persist()的无参版本,即调用persist(MEMORY_ONLY),将数据持久化到内存中。若需从内存中清除缓存,可使用unpersist()方法。RDD持久化还能手动选择不同策略,在调用persist()时传入对应的StorageLevel即可,比如可将RDD持久化在内存中、持久化到磁盘上、使用序列化的方式持久化,对持久化的数据进行多路复用[^3]。此外,cache()或者persist()的使用有规则,必须在transformation或者textFile等创建了一个RDD之后,直接连续调用cache()或persist()才有效,若先创建一个RDD,然后单独另起一行执行cache()或persist()方法,不仅无用还会报错[^5]。 - **应用场景**:对于迭代式算法和快速交互式应用,RDD持久化非常重要。因为在Spark中,RDD采用惰性求值机制,每次遇到action操作,Spark都会从头重新计算RDD及其所有的依赖,这对于迭代计算而言代价很大,迭代计算经常需多次重复使用同一组数据,使用RDD持久化可避免这种重复计算的开销。在某些场景下,巧妙使用RDD持久化,可对spark应用程序的性能有很大提升,甚至能将性能提升10倍[^1][^3][^4]。 以下是一个简单的Java代码示例,展示cache()的使用: ```java import org.apache.spark.SparkConf; import org.apache.spark.api.java.JavaRDD; import org.apache.spark.api.java.JavaSparkContext; public class RDDPersistenceExample { public static void main(String[] args) { SparkConf conf = new SparkConf().setAppName("RDDPersistenceExample").setMaster("local"); JavaSparkContext sc = new JavaSparkContext(conf); // 创建RDD并进行持久化 JavaRDD<String> lines = sc.textFile("E:\\server.log").cache(); long beginTime = System.currentTimeMillis(); System.out.println(lines.count()); long endTime = System.currentTimeMillis(); System.out.println("cost " + (endTime - beginTime) + " milliseconds."); beginTime = System.currentTimeMillis(); System.out.println(lines.count()); endTime = System.currentTimeMillis(); System.out.println("cost " + (endTime - beginTime) + " milliseconds."); sc.stop(); } } ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值