1、持久化的优势
Spark RDD是惰性求值的,如果简单地对RDD调用行动操作,Spark每次都会重算RDD以及它的所有依赖,为避免多次计算同一个RDD,可以通过persist()方法让Spark对数据进行持久化。
当我们让Spark持久化存储一个RDD时,计算出RDD的节点会分别保存它们所求出的分区数据。如果一个有持久化数据的节点发生故障,Spark会在需要用到缓存的数据时会重算丢失的数据分区。如果希望节点故障的情况不会拖累我们的执行速度,也可以将数据备份到多个节点上。
2、持久化级别
默认情况下persist()方法会把数据以序列化的形式缓存在JVM的堆空间中。
如果缓存的数据太多,内存中放不下,Spark会自动利用最近最少使用(LRU)的缓存策略把最老的分区从内存中移除。
对于仅把数据放在内存中的缓存级别,下一次要用到被移除的分区时需要重新计算。
对于使用内存和磁盘的缓存级别来说,被移除的分区都会写入磁盘。
级别 | 说明 |
---|---|
MEMORY_ONLY | 仅把数据放在内存中 |
MEMORY_ONLY_SER | 仅把数据放在内存中并序列化 |
MEMORY_AND_DISK | 如果数据在内存中放不下,则溢写到磁盘上 |
MEMORY_AND_DISK_SER | 如果数据在内存中放不下,则溢写到磁盘上,并序列化 |
DISK_ONLY | 仅把数据放在磁盘上 |
3、设置持久化级别
import org.apache.spark.storage.StorageLevel
val result = input.map(x => x+1)
result.persist(StorageLevel.DISK_ONLY)
注:
(1)如有必要,可以在缓存级别的末尾加上_2来将持久化数据存为两份,如DISK_ONLY_2
(2)cache()方法和persist()的默认缓存级别均为MEMORY_ONLY,persist()可支持多种缓存级别
4、手动移除持久化数据
使用unpersist()方法可以手动将持久化的RDD从缓存中移除。