天天看點

SparkCore>RDD的持久化/緩存

文章目錄

    • 引入
    • 持久化/緩存API詳解
    • 代碼示範
    • 總結

引入

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

持久化/緩存API詳解

  • persist方法和cache方法

    RDD通過persist或cache方法可以将前面的計算結果緩存,但是并不是這兩個方法被調用時立即緩存,而是觸發後面的action時,該RDD将會被緩存在計算節點的記憶體中,并供後面重用。

    通過檢視RDD的源碼發現cache最終也是調用了persist無參方法(預設存儲隻存在記憶體中)

    SparkCore>RDD的持久化/緩存

代碼示範

●啟動叢集和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 
//觸發action,會去讀取HDFS的檔案,rdd2會真正執行持久化
rdd2.sortBy(_._2,false).collect
//觸發action,會去讀緩存中的資料,執行速度會比之前快,因為rdd2已經持久化到記憶體中了
rdd2.sortBy(_._2,false).collect
           

●存儲級别

預設的存儲級别都是僅在記憶體存儲一份,Spark的存儲級别還有好多種,存儲級别在object StorageLevel中定義的

SparkCore>RDD的持久化/緩存
持久化級别 說明
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進行持久化/緩存

繼續閱讀