Spark缓存--persist方法
1. 功能本质
persist:这是一个通用的持久化方法,能够指定多种不同的存储级别。存储级别决定了数据的存储位置(如内存、磁盘)以及存储形式(如是否序列化)。
2. 存储级别指定
persist:可以通过传入 StorageLevel 参数来指定不同的持久化级别。常见的持久化级别有:
MEMORY_ONLY:将 RDD 以 Java 对象的形式存储在 JVM 的内存中。若内存不足,部分分区将不会被缓存,需要时会重新计算。
MEMORY_AND_DISK:优先把 RDD 以 Java 对象的形式存储在 JVM 的内存中。若内存不足,会把多余的分区存储到磁盘上。
DISK_ONLY:将 RDD 的数据存储在磁盘上。
MEMORY_ONLY_SER:将 RDD 以序列化的 Java 对象形式存储在内存中,相较于 MEMORY_ONLY,序列化后占用的内存空间更小,但读取时需要进行反序列化操作,会带来一定的性能开销。
MEMORY_AND_DISK_SER:优先将 RDD 以序列化的 Java 对象形式存储在内存中,内存不足时存储到磁盘上。
cache:不能指定存储级别,它固定使用 MEMORY_ONLY 存储级别。
3.persist的示例
下面我们以DISK_ONLY为例,改写上面的程序,验证它的持久化效果。具体要改动的地方有两个: 指定持久化地址; 把cache改成persist;
conf.set("spark.local.dir", "/path/to/your/local/dir")
sc = SparkContext(conf)
val cachedRDD = largeRDD.map(complexTransformation).persist(StorageLevel.MEMORY_ONLY)
4. persist()
的核心优势
-
灵活性:可根据数据大小、集群资源选择最优存储策略。
-
性能优化:
-
内存充足时用
MEMORY_ONLY
避免磁盘 IO。 -
内存不足时用
MEMORY_AND_DISK
避免频繁重计算。
-
-
资源平衡:通过序列化(如
MEMORY_ONLY_SER
)减少内存占用,降低 OOM 风险。
5. 何时使用 persist()
?
适用场景
-
迭代算法:如机器学习中的梯度下降、图计算的 PageRank。
-
多阶段计算:同一数据集被多次用于不同操作(如过滤、聚合、JOIN)。
-
交互式分析:在 Spark Shell 或 Notebook 中多次查询同一数据集。
不适用场景
-
数据仅使用一次:缓存反而浪费资源。
-
存储成本高于计算成本:如数据极大且后续操作简单。