在 Apache Spark 里,`persist` 方法是用于对 RDD(弹性分布式数据集)或 DataFrame 进行缓存操作的关键工具,其目的在于提升计算效率。以下将从原理、使用方法、存储级别等方面进行详细介绍:
### 原理
Spark 中的计算遵循惰性求值原则,每次行动操作触发时都会重新计算整个 RDD 谱系。而使用 `persist` 方法可以把 RDD 或 DataFrame 持久化到内存、磁盘或者两者皆有,这样在后续行动操作时就能直接使用缓存的数据,避免重复计算,从而提升性能。
### 使用方法
在 PySpark 里,`persist` 方法可以这样使用:
```python
from pyspark import SparkContext
from pyspark.storagelevel import StorageLevel
# 创建 SparkContext
sc = SparkContext("local", "PersistExample")
# 创建一个 RDD
rdd = sc.parallelize([1, 2, 3, 4, 5])
# 对 RDD 进行缓存,使用 MEMORY_ONLY 存储级别
rdd.persist(StorageLevel.MEMORY_ONLY)
# 触发行动操作
result = rdd.collect()
print(result)
# 后续再次使用该 RDD 时,会直接从缓存中获取数据
sum_result = rdd.sum()
print(sum_result)
# 释放缓存
rdd.unpersist()
```
在 Scala 中:
```scala
import org.apache.spark.SparkContext
import org.apache.spark.SparkConf
import org.apache.spark.storage.StorageLevel
// 创建 SparkConf 和 SparkContext
val conf = new SparkConf().setAppName("PersistExample").setMaster("local")
val sc = new SparkContext(conf)
// 创建一个 RDD
val rdd = sc.parallelize(Seq(1, 2, 3, 4, 5))
// 对 RDD 进行缓存,使用 MEMORY_ONLY 存储级别
rdd.persist(StorageLevel.MEMORY_ONLY)
// 触发行动操作
val result = rdd.collect()
println(result.mkString(", "))
// 后续再次使用该 RDD 时,会直接从缓存中获取数据
val sumResult = rdd.sum()
println(sumResult)
// 释放缓存
rdd.unpersist()
```
### 存储级别
`persist` 方法接受一个 `StorageLevel` 参数,它定义了数据的存储方式,常见的存储级别有:
- **MEMORY_ONLY**:将数据以反序列化的 Java 对象形式存储在 JVM 内存中。若内存不足,部分分区将不会被缓存,在需要时重新计算。
- **MEMORY_ONLY_SER**:把数据以序列化的形式存储在 JVM 内存中,相较于反序列化形式,占用内存更少,但读取时需要反序列化,会增加 CPU 开销。
- **MEMORY_AND_DISK**:先尝试将数据以反序列化的 Java 对象形式存储在 JVM 内存中,若内存不足,将多余的分区存储到磁盘。
- **MEMORY_AND_DISK_SER**:先尝试将数据以序列化的形式存储在 JVM 内存中,内存不够时,把多余的分区存到磁盘。
- **DISK_ONLY**:把数据存储在磁盘上。
### 注意事项
- **缓存的触发**:`persist` 方法只是标记 RDD 或 DataFrame 需要被缓存,真正的缓存操作是在第一次行动操作触发时进行的。
- **释放缓存**:当不再需要缓存的数据时,要使用 `unpersist` 方法释放缓存,以避免占用过多的系统资源。
395

被折叠的 条评论
为什么被折叠?



