RDD的持久化/緩存

在實際開發中某些RDD的計算或轉換可能會比較耗費時間,如果這些RDD後續還會頻繁的被使用到,那麼可以將這些RDD進行持久化/緩存,這樣下次再使用到的時候就不用再重新計算了,提高了程序運行的效率

持久化/緩存API詳解

persist方法和cache方法

RDD通過persistcache方法可以將前面的計算結果緩存,但是並不是這兩個方法被調用時立即緩存,而是觸發後面的action,該RDD將會被緩存在計算節點的內存中,並供後面重用。

通過查看RDD的源碼發現cache最終也是調用了persist無參方法(默認存儲只存在內存中)

代碼演示

啓動集羣和spark-shell

/export/servers/spark/sbin/start-all.sh
/export/servers/spark/bin/spark-shell \
--master spark://node01:7077,node02:7077 \
--executor-memory 1g \
--total-executor-cores 2

將一個RDD持久化,後續操作該RDD就可以直接從緩存中拿

val rdd1 = sc.textFile("hdfs://node01:8020/wordcount/input/words.txt")
val rdd2 = rdd1.flatMap(x=>x.split(" ")).map((_,1)).reduceByKey(_+_)
rdd2.cache //緩存/持久化
rdd2.sortBy(_._2,false).collect//觸發action,會去讀取HDFS的文件,rdd2會真正執行持久化
rdd2.sortBy(_._2,false).collect//觸發action,會去讀緩存中的數據,執行速度會比之前快,因爲rdd2已經持久化到內存中了

存儲級別

默認的存儲級別都是僅在內存存儲一份,Spark的存儲級別還有好多種,存儲級別在object StorageLevel中定義的

 

持久化級別

說明

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類似,但將數據存儲在堆外內存中。 (即不是直接存儲在JVM內存中)

如:Tachyon-分佈式內存存儲系統、Alluxio - Open Source Memory Speed Virtual Distributed Storage

總結

1.RDD持久化/緩存的目的是爲了提高後續操作的速度

2.緩存的級別有很多,默認只存在內存中,開發中使用memory_and_disk

3.只有執行action操作的時候纔會真正將RDD數據進行持久化/緩存

4.實際開發中如果某一個RDD後續會被頻繁的使用,可以將該RDD進行持久化/緩存

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