RDD的緩存

概述程序員

相比Hadoop MapReduce來講,Spark計算具備巨大的性能優點,其中很大一部分緣由是Spark對於內存的充分利用,以及提供的緩存機制。apache

RDD持久化(緩存)數組

持久化在早期被稱做緩存(cache),但緩存通常指將內容放在內存中。雖然持久化操做在絕大部分狀況下都是將RDD緩存在內存中,但通常都會在內存不夠時用磁盤頂上去(比操做系統默認的磁盤交換性能高不少)。固然,也能夠選擇不使用內存,而是僅僅保存到磁盤中。因此,如今Spark使用持久化(persistence)這一更普遍的名稱。緩存

若是一個RDD不止一次被用到,那麼就能夠持久化它,這樣能夠大幅提高程序的性能,甚至達10倍以上。框架

默認狀況下,RDD只使用一次,用完即扔,再次使用時須要從新計算獲得,而持久化操做避免了這裏的重複計算,實際測試也顯示持久化對性能提高明顯,這也是Spark剛出現時被人稱爲內存計算框架的緣由函數

假設首先進行了RDD0→RDD1→RDD2的計算做業,那麼計算結束時,RDD1就已經緩存在系統中了。在進行RDD0→RDD1→RDD3的計算做業時,因爲RDD1已經緩存在系統中,所以RDD0→RDD1的轉換不會重複進行,計算做業只須進行RDD1→RDD3的計算就能夠了,所以計算速度能夠獲得很大提高。oop

持久化的方法是調用persist()函數,除了持久化至內存中,還能夠在persist()中指定storage level參數使用其餘的類型,具體以下:性能

 

1MEMORY_ONLY : 將 RDD 以反序列化的 Java 對象的形式存儲在 JVM 中. 若是內存空間不夠,部分數據分區將不會被緩存,在每次須要用到這些數據時從新進行計算. 這是默認的級別。測試

 

cache()方法對應的級別就是MEMORY_ONLY級別加密

 

2MEMORY_AND_DISK:將 RDD 以反序列化的 Java 對象的形式存儲在 JVM 中。

若是內存空間不夠,將未緩存的數據分區存儲到磁盤,在須要使用這些分區時從磁盤讀取。

 

3MEMORY_ONLY_SER :將 RDD 以序列化的 Java 對象的形式進行存儲(每一個分區爲一個 byte 數組)。這種方式會比反序列化對象的方式節省不少空間,尤爲是在使用 fast serialize時會節省更多的空間,可是在讀取時會使得 CPU 的 read 變得更加密集。若是內存空間不夠,部分數據分區將不會被緩存,在每次須要用到這些數據時從新進行計算。

 

4MEMORY_AND_DISK_SER :相似於 MEMORY_ONLY_SER ,可是溢出的分區會存儲到磁盤,而不是在用到它們時從新計算。若是內存空間不夠,將未緩存的數據分區存儲到磁盤,在須要使用這些分區時從磁盤讀取。

 

5DISK_ONLY:只在磁盤上緩存 RDD。

 

6MEMORY_ONLY_2, MEMORY_AND_DISK_2, etc. :與上面的級別功能相同,

只不過每一個分區在集羣中兩個節點上創建副本。

 

7)OFF_HEAP 將數據存儲在 off-heap memory 中。使用堆外內存,這是Java虛擬機裏面的概念,堆外內存意味着把內存對象分配在Java虛擬機的堆之外的內存,這些內存直接受操做系統管理(而不是虛擬機)。使用堆外內存的好處:可能會利用到更大的內存存儲空間。可是對於數據的垃圾回收會有影響,須要程序員來處理

注意,可能帶來一些GC回收問題

Spark 也會自動持久化一些在 shuffle 操做過程當中產生的臨時數據(好比 reduceByKey),即使是用戶並無調用持久化的方法。這樣作能夠避免當 shuffle 階段時若是一個節點掛掉了就得從新計算整個數據的問題。若是用戶打算屢次重複使用這些數據,咱們仍然建議用戶本身調用持久化方法對數據進行持久化。

 

使用緩存

scala> import org.apache.spark.storage._

scala> val rdd1=sc.makeRDD(1 to 5)

scala> rdd1.cache  //cache只有一種默認的緩存級別,即MEMORY_ONLY

scala> rdd1.persist(StorageLevel.MEMORY_ONLY)

緩存數據的清除

Spark 會自動監控每一個節點上的緩存數據,而後使用 least-recently-used (LRU) 機制來處理舊的緩存數據。若是你想手動清理這些緩存的 RDD 數據而不是去等待它們被自動清理掉,

可使用 RDD.unpersist( ) 方法。

相關文章
相關標籤/搜索