Spark中RDD 持久化操作 cache與persist區別

Spark中RDD 持久化操作 cache與persist區別
原創小鵝鵝 最後發佈於2018-07-02 15:33:13 閱讀數 1712  收藏
展開
環境/背景
Spark 2.3.0
Scala 2.11
Java 1.8

在進行RDD操作的時候,我們需要在接下來多個行動中重用同一個RDD,這個時候我們就可以將RDD緩存起來,可以很大程度的節省計算和程序運行時間。

接下來可以通過查看Spark的源碼對比RDD.cache()與RDD.persist()的差別。

cache 與 persist 對比
首先從JavaRDD類中點進去看JavaRDD.cache()方法與JavaRDD.persist()方法:

JavaRDD.scala

  /**
   * Persist this RDD with the default storage level (`MEMORY_ONLY`).
   */
  def cache(): JavaRDD[T] = wrapRDD(rdd.cache())

  /**
   * Set this RDD's storage level to persist its values across operations after the first time
   * it is computed. This can only be used to assign a new storage level if the RDD does not
   * have a storage level set yet..
   */
  def persist(newLevel: StorageLevel): JavaRDD[T] = wrapRDD(rdd.persist(newLevel))

在JavaRDD中說得挺明白:

cache()只是緩存到默認的緩存級別:只使用內存
persist()可以自定義緩存級別
我們再點進去看看RDD.scala的描述:

RDD.scala

  /**
   * Set this RDD's storage level to persist its values across operations after the first time
   * it is computed. This can only be used to assign a new storage level if the RDD does not
   * have a storage level set yet. Local checkpointing is an exception.
   */
  def persist(newLevel: StorageLevel): this.type = {
    if (isLocallyCheckpointed) {
      // This means the user previously called localCheckpoint(), which should have already
      // marked this RDD for persisting. Here we should override the old storage level with
      // one that is explicitly requested by the user (after adapting it to use disk).
      persist(LocalRDDCheckpointData.transformStorageLevel(newLevel), allowOverride = true)
    } else {
      persist(newLevel, allowOverride = false)
    }
  }

  /**
   * Persist this RDD with the default storage level (`MEMORY_ONLY`).
   */
  def persist(): this.type = persist(StorageLevel.MEMORY_ONLY)

  /**
   * Persist this RDD with the default storage level (`MEMORY_ONLY`).
   */
  def cache(): this.type = persist()

如果我們直接調用cache()或者沒有入參的persist(),效果是一樣的,都是使用默認的storage level
如果需要自定義緩存級別,可以通過傳入StorageLevel類裏面的設置好的對象使用。

緩存級別
我們再點進去StorageLevel.scala裏面看看是怎麼定義的:

StorageLevel.scala

其中StorageLevel的構造函數如下:

/**
 * :: DeveloperApi ::
 * Flags for controlling the storage of an RDD. Each StorageLevel records whether to use memory,
 * or ExternalBlockStore, whether to drop the RDD to disk if it falls out of memory or
 * ExternalBlockStore, whether to keep the data in memory in a serialized format, and whether
 * to replicate the RDD partitions on multiple nodes.
 *
 * The [[org.apache.spark.storage.StorageLevel]] singleton object contains some static constants
 * for commonly useful storage levels. To create your own storage level object, use the
 * factory method of the singleton object (`StorageLevel(...)`).
 */
@DeveloperApi
class StorageLevel private(
    private var _useDisk: Boolean,
    private var _useMemory: Boolean,
    private var _useOffHeap: Boolean,
    private var _deserialized: Boolean,
    private var _replication: Int = 1)
  extends Externalizable {

可以看到StorageLevel類的主構造器包含了5個參數:

useDisk:使用硬盤(外存)
useMemory:使用內存
useOffHeap:使用堆外內存,這是Java虛擬機裏面的概念,堆外內存意味着把內存對象分配在Java虛擬機的堆以外的內存,這些內存直接受操作系統管理(而不是虛擬機)。這樣做的結果就是能保持一個較小的堆,以減少垃圾收集對應用的影響。
deserialized:反序列化,其逆過程序列化(Serialization)是java提供的一種機制,將對象表示成一連串的字節;而反序列化就表示將字節恢復爲對象的過程。序列化是對象永久化的一種機制,可以將對象及其屬性保存起來,並能在反序列化後直接恢復這個對象
replication:備份數(在多個節點上備份)
舉個栗子:

val MEMORY_AND_DISK_SER_2 = new StorageLevel(true, true, false, false, 2) 
1
就表示使用這種緩存級別的RDD將存儲在硬盤以及內存中,使用序列化(在硬盤中),並且在多個節點上備份2份(正常的RDD只有一份)

另外還注意到有一種特殊的緩存級別

val OFF_HEAP = new StorageLevel(false, false, true, false)
1
使用了堆外內存,StorageLevel 類的源碼中有一段代碼可以看出這個的特殊性,它不能和其它幾個參數共存。

if (useOffHeap) {
  require(!useDisk, "Off-heap storage level does not support using disk")
  require(!useMemory, "Off-heap storage level does not support using heap memory")
  require(!deserialized, "Off-heap storage level does not support deserialized storage")
  require(replication == 1, "Off-heap storage level does not support multiple replication")
}
————————————————
版權聲明:本文爲CSDN博主「小鵝鵝」的原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/asd136912/article/details/80885136

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章