天天看點

[Spark]Spark RDD 指南五 持久化

1. 概述

Spark中最重要的功能之一是操作時在記憶體中持久化(緩存)資料集(persisting (or caching) a dataset in memory across operations)。當我們讓Spark持久化存儲一個RDD時,每個節點都會将其計算的任何分區存儲在記憶體中,并将其重用于該資料集(或從其派生的資料集)的其他行動操作(each node stores any partitions of it that it computes in memory and reuses them in other actions on that dataset (or datasets derived from it))。這樣可以使以後的動作操作執行的更快(通常超過10倍)。 緩存是疊代算法和快速互動使用的關鍵工具。

可以使用RDD上的

persist()

cache()

方法來标記要持久化的RDD(執行persist和cache方法不會持久化RDD)。 當RDD第一次在動作操作中計算時,它将持久化(緩存)到節點的記憶體中。Spark的緩存是可容錯的 - 如果RDD的任何分區丢失,它将使用最初建立的轉換操作自動重新計算。

https://note.youdao.com/md/preview/preview.html?file=%2Fyws%2Fapi%2Fpersonal%2Ffile%2FWEBfcf73a53c66d9d105a6586d24518c651%3Fmethod%3Ddownload%26read%3Dtrue#2-%E5%AD%98%E5%82%A8%E7%BA%A7%E5%88%AB 2. 存儲級别

除此之外,可以使用不同的持久化級别來存儲每個持久化的RDD,進而允許你将資料集保留在磁盤上,或者将其以序列化的Java對象存儲在記憶體中(以節省空間),或者将其複制到所有節點上( to persist the dataset on disk, persist it in memory but as serialized Java objects (to save space), replicate it across nodes)。通過将StorageLevel對象傳遞給persist()方法來設定持久化級别。 cache()方法使用預設存儲級别,即

StorageLevel.MEMORY_ONLY

持久化級别 說明
MEMORY_ONLY 将RDD以非序列化的Java對象存儲在JVM中。 如果沒有足夠的記憶體存儲RDD,則某些分區将不會被緩存,每次需要時都會重新計算。 這是預設級别。
MEMORY_AND_DISK 将RDD以非序列化的Java對象存儲在JVM中。如果資料在記憶體中放不下,則溢寫到磁盤上.需要時則會從磁盤上讀取
MEMORY_ONLY_SER (Java and Scala) 将RDD以序列化的Java對象(每個分區一個位元組數組)的方式存儲.這通常比非序列化對象(deserialized objects)更具空間效率,特别是在使用快速序列化的情況下,但是這種方式讀取資料會消耗更多的CPU。
MEMORY_AND_DISK_SER (Java and Scala)

MEMORY_ONLY_SER

類似,但如果資料在記憶體中放不下,則溢寫到磁盤上,而不是每次需要重新計算它們。
DISK_ONLY 将RDD分區存儲在磁盤上。
MEMORY_ONLY_2, MEMORY_AND_DISK_2等 與上面的儲存級别相同,隻不過将持久化資料存為兩份,備份每個分區存儲在兩個叢集節點上。
OFF_HEAP(實驗中)

MEMORY_ONLY_SER

類似,但将資料存儲在堆記憶體中。 這需要啟用堆記憶體。

備注

在Python中,存儲對象将始終使用

Pickle

庫進行序列化,持久化級别預設值就是以序列化後的對象存儲在JVM堆空間中,是以選擇什麼樣的序列化級别是無關緊要的。 當我們把資料寫到磁盤或者堆外存儲上時,也總是使用序列化後的資料.Python中的可用存儲級别包括

MEMORY_ONLY

MEMORY_ONLY_2

MEMORY_AND_DISK

MEMORY_AND_DISK_2

DISK_ONLY

DISK_ONLY_2

在Shuffle操作中(例如,reduceByKey),即使使用者沒有主動對資料進行持久化,Spark也會對一些中間資料進行持久化。 這樣做是為了避免重新計算整個輸入,如果一個節點在Shuffle過程中發生故障。 如果要重用,我們仍然建議使用者對生成的RDD進行持久性。

https://note.youdao.com/md/preview/preview.html?file=%2Fyws%2Fapi%2Fpersonal%2Ffile%2FWEBfcf73a53c66d9d105a6586d24518c651%3Fmethod%3Ddownload%26read%3Dtrue#3-%E9%80%89%E6%8B%A9%E5%AD%98%E5%82%A8%E7%BA%A7%E5%88%AB 3. 選擇存儲級别

Spark的存儲級别旨在提供記憶體使用率和CPU效率之間的不同權衡。 我們建議通過以下過程來選擇一個:

  • 如果你的RDD适合于預設存儲級别(MEMORY_ONLY),那就保持不動。 這是CPU效率最高的選項,允許RDD上的操作盡可能快地運作。
  • 如果不是,請嘗試使用

    MEMORY_ONLY_SER

    并選擇一個快速的序列化庫,這種方式更加節省空間,并仍然能夠快速通路。 (Java和Scala)
  • 不要溢寫到磁盤,除非在資料集上的計算操作成本較高,或者需要過濾大量的資料。 否則,重新計算分區可能與從磁盤讀取分區一樣快。
  • 如果要快速故障恢複(例如,使用Spark為Web應用程式提供服務),請使用副本存儲級别

    replicated storage levels

    。 所有存儲級别通過重新計算丢失的資料來提供完整的容錯能力,但副本資料可讓你繼續在RDD上運作任務,而無需重新計算丢失的分區。

https://note.youdao.com/md/preview/preview.html?file=%2Fyws%2Fapi%2Fpersonal%2Ffile%2FWEBfcf73a53c66d9d105a6586d24518c651%3Fmethod%3Ddownload%26read%3Dtrue#4-%E6%B8%85%E9%99%A4%E6%95%B0%E6%8D%AE 4. 清除資料

Spark會自動監視每個節點的緩存使用情況,并以最近最少使用(LRU)方式丢棄舊的資料分區。 如果您想手動删除RDD,而不是等待它自動從緩存中删除,請使用

RDD.unpersist()

方法。

原文:

http://spark.apache.org/docs/latest/programming-guide.html#rdd-persistence