1. 程式人生 > >Spark核心程式設計之RDD持久化詳解

Spark核心程式設計之RDD持久化詳解

RDD持久化原理

Spark非常重要的一個功能特性就是可以將RDD持久化在記憶體中。當對RDD執行持久化操作時,每個節點都會將自己操作的RDD的partition持久化到記憶體中,並且在之後對該RDD的反覆使用中,直接使用記憶體快取的partition。這樣的話,對於針對一個RDD反覆執行多個操作的場景,就只要對RDD計算一次即可,後面直接使用該RDD,而不需要反覆計算多次該RDD。

巧妙使用RDD持久化,甚至在某些場景下,可以將spark應用程式的效能提升10倍。對於迭代式演算法和快速互動式應用來說,RDD持久化,是非常重要的。

要持久化一個RDD,只要呼叫其cache()或者persist()方法即可。在該RDD第一次被計算出來時,就會直接快取在每個節點中。而且Spark的持久化機制還是自動容錯的,如果持久化的RDD的任何partition丟失了,那麼Spark會自動通過其源RDD,使用transformation操作重新計算該partition。

cache()和persist()的區別在於,cache()是persist()的一種簡化方式,cache()的底層就是呼叫的persist()的無參版本,同時就是呼叫persist(MEMORY_ONLY),將資料持久化到記憶體中。如果需要從記憶體中清楚快取,那麼可以使用unpersist()方法。

Spark自己也會在shuffle操作時,進行資料的持久化,比如寫入磁碟,主要是為了在節點失敗時,避免需要重新計算整個過程。

圖解持久化和不持久化

不使用RDD持久化的問題的原理

這裡寫圖片描述

RDD持久化的工作原理

這裡寫圖片描述

RDD持久化實戰

package cn.spark.study
.core; import org.apache.spark.SparkConf; import org.apache.spark.api.java.JavaRDD; import org.apache.spark.api.java.JavaSparkContext; /** * RDD持久化 * @author Administrator * */ public class Persist { public static void main(String[] args) { SparkConf conf = new SparkConf() .setAppName
("Persist") .setMaster("local"); JavaSparkContext sc = new JavaSparkContext(conf); // cache()或者persist()的使用,是有規則的 // 必須在transformation或者textFile等建立了一個RDD之後,直接連續呼叫cache()或persist()才可以 // 如果你先建立一個RDD,然後單獨另起一行執行cache()或persist()方法,是沒有用的 // 而且,會報錯,大量的檔案會丟失 JavaRDD<String> lines = sc.textFile("C://Users//Administrator//Desktop//spark.txt") .cache(); long beginTime = System.currentTimeMillis(); long count = lines.count(); System.out.println(count); long endTime = System.currentTimeMillis(); System.out.println("cost " + (endTime - beginTime) + " milliseconds."); beginTime = System.currentTimeMillis(); count = lines.count(); System.out.println(count); endTime = System.currentTimeMillis(); System.out.println("cost " + (endTime - beginTime) + " milliseconds."); sc.close(); } }

RDD持久化策略

RDD持久化是可以手動選擇不同的策略的。比如可以將RDD持久化在記憶體中、持久化到磁碟上、使用序列化的方式持久化,多持久化的資料進行多路複用。只要在呼叫persist()時傳入對應的StorageLevel即可。
這裡寫圖片描述
這裡寫圖片描述

如何選擇RDD持久化策略?

Spark提供的多種持久化級別,主要是為了在CPU和記憶體消耗之間進行取捨。下面是一些通用的持久化級別的選擇建議:

1、優先使用MEMORY_ONLY,如果可以快取所有資料的話,那麼就使用這種策略。因為純記憶體速度最快,而且沒有序列化,不需要消耗CPU進行反序列化操作。
2、如果MEMORY_ONLY策略,無法儲存的下所有資料的話,那麼使用MEMORY_ONLY_SER,將資料進行序列化進行儲存,純記憶體操作還是非常快,只是要消耗CPU進行反序列化。
3、如果需要進行快速的失敗恢復,那麼就選擇帶字尾為_2的策略,進行資料的備份,這樣在失敗時,就不需要重新計算了。
4、能不使用DISK相關的策略,就不用使用,有的時候,從磁碟讀取資料,還不如重新計算一次。