spark效能調優之重構RDD架構,RDD持久化
當第一次對RDD2執行運算元,獲取RDD3的時候,就會從RDD1開始計算,就是讀取HDFS檔案,然後對RDD1執行運算元,獲取到RDD2,然後再計算,得到RDD3
預設情況下,多次對一個RDD執行運算元,去獲取不同的RDD;都會對這個RDD以及之前的父RDD,全部重新計算一次;讀取HDFS->RDD1->RDD2-RDD4
這種情況,是絕對絕對,一定要避免的,一旦出現一個RDD重複計算的情況,就會導致效能急劇降低。
比如,HDFS->RDD1-RDD2的時間是15分鐘,那麼此時就要走兩遍,變成30分鐘
另外一種情況,從一個RDD到幾個不同的RDD,運算元和計算邏輯其實是完全一樣的,結果因為人為的疏忽,計算了多次,獲取到了多個RDD。
所以,建議採用以下方法可以優化:
第一,RDD架構重構與優化
儘量去複用RDD,差不多的RDD,可以抽取稱為一個共同的RDD,供後面的RDD計算時,反覆使用。
第二,公共RDD一定要實現持久化
持久化,也就是說,將RDD的資料快取到記憶體中/磁碟中,(BlockManager),以後無論對這個RDD做多少次計算,那麼都是直接取這個RDD的持久化的資料,比如從記憶體中或者磁碟中,直接提取一份資料。
第三,持久化,是可以進行序列化的
如果正常將資料持久化在記憶體中,那麼可能會導致記憶體的佔用過大,這樣的話,也許,會導致OOM記憶體溢位。
當純記憶體無法支撐公共RDD資料完全存放的時候,就優先考慮,使用序列化的方式在純記憶體中儲存。將RDD的每個partition的資料,序列化成一個大的位元組陣列,就一個物件;序列化後,大大減少記憶體的空間佔用。
序列化的方式,唯一的缺點就是,在獲取資料的時候,需要反序列化。
如果序列化純記憶體方式,還是導致OOM,記憶體溢位;就只能考慮磁碟的方式,記憶體+磁碟的普通方式(無序列化)。記憶體+磁碟,序列化。
第四,為了資料的高可靠性,而且記憶體充足,可以使用雙副本機制,進行持久化
持久化的雙副本機制,持久化後的一個副本,因為機器宕機了,副本丟了,就還是得重新計算一次;持久化的每個資料單元,儲存一份副本,放在其他節點上面;從而進行容錯;一個副本丟了,不用重新計算,還可以使用另外一份副本。這種方式,僅僅針對你的記憶體資源極度充足。