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) | 與 類似,但如果資料在記憶體中放不下,則溢寫到磁盤上,而不是每次需要重新計算它們。 |
DISK_ONLY | 将RDD分區存儲在磁盤上。 |
MEMORY_ONLY_2, MEMORY_AND_DISK_2等 | 與上面的儲存級别相同,隻不過将持久化資料存為兩份,備份每個分區存儲在兩個叢集節點上。 |
OFF_HEAP(實驗中) | 類似,但将資料存儲在堆記憶體中。 這需要啟用堆記憶體。 |
備注
在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上的操作盡可能快地運作。
- 如果不是,請嘗試使用
并選擇一個快速的序列化庫,這種方式更加節省空間,并仍然能夠快速通路。 (Java和Scala)MEMORY_ONLY_SER
- 不要溢寫到磁盤,除非在資料集上的計算操作成本較高,或者需要過濾大量的資料。 否則,重新計算分區可能與從磁盤讀取分區一樣快。
- 如果要快速故障恢複(例如,使用Spark為Web應用程式提供服務),請使用副本存儲級别
。 所有存儲級别通過重新計算丢失的資料來提供完整的容錯能力,但副本資料可讓你繼續在RDD上運作任務,而無需重新計算丢失的分區。replicated storage levels
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