spark持久化

日常開發中每次讀取大文件都比較費時費力,而每次的重複讀取都是資源的浪費,針對這些問題spark也提供了持久化的解決方案,幫助我們解決諸如此類的效率問題,先來看一段我搜集到的資料:

RDD 持久化

Spark 中一個很重要的能力是將數據持久化(或稱爲緩存),在多個操作間都可以訪問這些持久化的數據。當持久化一個 RDD 時,每個節點的其它分區都可以使用 RDD 在內存中進行計算,在該數據上的其他 action 操作將直接使用內存中的數據。這樣會讓以後的 action 操作計算速度加快(通常運行速度會加速 10 倍)。緩存是迭代算法和快速的交互式使用的重要工具。

RDD 可以使用 persist() 方法或 cache() 方法進行持久化。數據將會在第一次 action 操作時進行計算,並緩存在節點的內存中。Spark 的緩存具有容錯機制,如果一個緩存的 RDD 的某個分區丟失了,Spark 將按照原來的計算過程,自動重新計算並進行緩存。

在 shuffle 操作中(例如 reduceByKey),即便是用戶沒有調用 persist 方法,Spark 也會自動緩存部分中間數據。這麼做的目的是,在 shuffle 的過程中某個節點運行失敗時,不需要重新計算所有的輸入數據。如果用戶想多次使用某個 RDD,強烈推薦在該 RDD 上調用 persist 方法。


存儲級別

每個持久化的 RDD 可以使用不同的存儲級別進行緩存,例如,持久化到磁盤、已序列化的 Java 對象形式持久化到內存(可以節省空間)、跨節點間複製、以 off-heap 的方式存儲在 Tachyon。這些存儲級別通過傳遞一個 StorageLevel 對象給 persist() 方法進行設置。
詳細的存儲級別介紹如下:

    MEMORY_ONLY : 將 RDD 以反序列化 Java 對象的形式存儲在 JVM 中。如果內存空間不夠,部分數據分區將不再緩存,在每次需要用到這些數據時重新進行計算。這是默認的級別。
    MEMORY_AND_DISK : 將 RDD 以反序列化 Java 對象的形式存儲在 JVM 中。如果內存空間不夠,將未緩存的數據分區存儲到磁盤,在需要使用這些分區時從磁盤讀取。
    MEMORY_ONLY_SER : 將 RDD 以序列化的 Java 對象的形式進行存儲(每個分區爲一個 byte 數組)。這種方式會比反序列化對象的方式節省很多空間,尤其是在使用 fast serializer時會節省更多的空間,但是在讀取時會增加 CPU 的計算負擔。
    MEMORY_AND_DISK_SER : 類似於 MEMORY_ONLY_SER ,但是溢出的分區會存儲到磁盤,而不是在用到它們時重新計算。
    DISK_ONLY : 只在磁盤上緩存 RDD。
    MEMORY_ONLY_2,MEMORY_AND_DISK_2,等等 : 與上面的級別功能相同,只不過每個分區在集羣中兩個節點上建立副本。
    OFF_HEAP(實驗中): 類似於 MEMORY_ONLY_SER ,但是將數據存儲在 off-heap memory,這需要啓動 off-heap 內存。

注意,在 Python 中,緩存的對象總是使用 Pickle 進行序列化,所以在 Python 中不關心你選擇的是哪一種序列化級別。python 中的存儲級別包括 MEMORY_ONLY,MEMORY_ONLY_2,MEMORY_AND_DISK,MEMORY_AND_DISK_2,DISK_ONLY 和 DISK_ONLY_2 。

上面的幾個緩存級別是官網給出的,但是通過源碼看,實際上一共有12種緩存級別

 

package com.debug;

import org.apache.spark.SparkConf;
import org.apache.spark.api.java.JavaRDD;
import org.apache.spark.api.java.JavaSparkContext;
import org.apache.spark.api.java.function.VoidFunction;
import org.apache.spark.storage.StorageLevel;

/**
 * @author cry
 *RDD的持久化
 */
public class UseRDD02 {

	public static void main(String[] args) {
		SparkConf conf=new SparkConf();
		conf.setMaster("local");
		conf.setAppName("rddpersist");
		
		JavaSparkContext sc=new JavaSparkContext(conf);
		
		//讀取字數統計txt文件
		JavaRDD<String> lines=sc.textFile("/home/cry/word1.txt");
		
		//lines=lines.cache();
		lines=lines.persist(StorageLevel.MEMORY_AND_DISK());
		
		lines.foreach(new VoidFunction<String>() {
		
			public void call(String line) throws Exception {
				System.out.println(line);
				
			}
		});
		
		sc.stop();

		
		

	}

}


這段代碼沒有對讀取時間做打印輸出,如有必要可以自己加上測試下

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