persist和cache原理和使用

本文探讨了Spark中的persist原理,包括其初衷是为了避免重复计算,通过StorageLevel定义的不同持久化级别实现数据的内存和磁盘存储。同时,文章介绍了persist在特定使用场景下的应用,如耗时计算、长链条任务和shuffle操作前后。默认持久化级别为MEMORY_ONLY,而OFF_HEAP利用堆外内存以减少GC影响。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

persist和cache原理和使用

// org.apache.spark.rdd/rdd.scala
def cache(): this.type = persist()
def persist(): this.type = persist(StorageLevel.MEMORY_ONLY)

cache基于persist实现,本文重点对persist进行研究

1.persist原理

1.1 persist初衷

Spark基于内存进行计算,不会缓存中间结果,如果计算中多次引用同一个RDD,那么每一次对该RDD的引用都会在action触发计算时重新计算该RDD,会导致大量的重复计算,Spark提供了一种RDD的持久化机制来实现RDD重用,即用调用rdd.persist()方法标记rdd需要持久化,在下一次计算该rdd时会将rdd的计算结果进行持久化。

1.2 持久化级别

// org.apache.spark.storage/StorageLevel.scala
class StorageLevel private(
    private var _useDisk: Boolean,
    private var _useMemory: Boolean,
    private var _useOffHeap: Boolean,
    private var _deserialized: Boolean,
    private var _replication: Int = 1)

object StorageLevel {
  val NONE = new StorageLevel(false, false, false, false)
  val DISK_ONLY = new StorageLevel(true, false, false, false)
  val DISK_ONLY_2 = new StorageLevel(true, false, false, false, 2)
  val MEMORY_ONLY = new StorageLevel(false, true, false, true)
  val MEMORY_ONLY_2 = new StorageLevel(false, true, false, true, 2)
  val MEMORY_ONLY_SER = new StorageLevel(false, true, false, false)
  val MEMORY_ONLY_SER_2 = new StorageLevel(false, true, false, false, 2)
  val MEMORY_AND_DISK = new StorageLevel(true, true, false, true)
  val MEMORY_AND_DISK_2 = new StorageLevel(true, true, false, true, 2)
  val MEMORY_AND_DISK_SER = new StorageLevel(true, true, false, false)
  val MEMORY_AND_DISK_SER_2 = new StorageLevel(true, true, false, false, 2)
  val OFF_HEAP = new StorageLevel(true, true, true, false, 1)
}

StorageLevel类的成员变量

  • _useDisk:是否使用磁盘
  • _useMemory:是否使用内存
  • _useOffHeap:是否使用堆外内存
  • _deserialized:是否进行序列化
  • _replication:副本数

StorageLevel伴随对象的12个持久化级别对象

磁盘内存堆外内存序列化副本数
NONE0
DISK_ONLY1
DISK_ONLY_22
MEMORY_ONLY1
MEMORY_ONLY_22
MEMORY_ONLY_SER1
MEMORY_ONLY_SER_22
MEMORY_AND_DISK1
MEMORY_AND_DISK_22
MEMORY_AND_DISK_SER1
MEMORY_AND_DISK_SER_22
OFF_HEAP1

说明

  • 同时使用memory和disk时,优先使用内存,内存不足使用磁盘,磁盘不足时从头重新计算
  • OFF_HEAP只使用堆外内存,在内存有限时,可以减少频繁GC及不必要的内存消耗,提升程序性能,但是没有数据备份,数据丢失需要重新计算
  • RDD的默认持久化级别是NONE,即不进行持久化
  • persist默认持久化级别为MEMORY_ONLY
// org.apache.spark.rdd/rdd.scala
abstract class RDD[T: ClassTag](
    @transient private var _sc: SparkContext,
    @transient private var deps: Seq[Dependency[_]]
  ) extends Serializable with Logging {
  
  private var storageLevel: StorageLevel = StorageLevel.NONE //RDD默认持久化级别

}

2.persist使用场景

  • 某个步骤计算非常耗时,需要进行persist持久化
  • 计算链条非常长,重新恢复要算很多步骤
  • 需要checkpoint的RDD最好进行persist,checkpoint机制会在job执行完成之后根据DAG向前回溯,找到需要进行checkpoint的RDD,另起一个job来计算该RDD,将计算结果存储到HDFS,如果在job执行的过程中对该RDD进行了persist,那么进行checkpoint会非常快
  • shuffle之前进行persist,Spark默认将数据持久化到磁盘,自动完成,无需干预
  • shuffle之后为什么要persist,shuffle要进性网络传输,风险很大,数据丢失重来,恢复代价很大
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值