天天看點

(十九)性能調優之RDD持久化

(十九)性能調優之RDD持久化

第一,RDD架構重構與優化

盡量去複用RDD,差不多的RDD,可以抽取稱為一個共同的RDD,供後面的RDD計算時,反複使用。

第二,公共RDD一定要實作持久化

北方吃餃子,現包現煮。你人來了,要點一盤餃子。餡料+餃子皮+水->包好的餃子,對包好的餃子去煮,煮開了以後,才有你需要的熟的,熱騰騰的餃子。

現實生活中,餃子現包現煮,當然是最好的了;但是Spark中,RDD要去“現包現煮”,那就是一場緻命的災難。

對于要多次計算和使用的公共RDD,一定要進行持久化。

持久化,也就是說,将RDD的資料緩存到記憶體中/磁盤中,(BlockManager),以後無論對這個RDD做多少次計算,那麼都是直接取這個RDD的持久化的資料,比如從記憶體中或者磁盤中,直接提取一份資料。

第三,持久化,是可以進行序列化的

如果正常将資料持久化在記憶體中,那麼可能會導緻記憶體的占用過大,這樣的話,也許,會導緻OOM記憶體溢出。

當純記憶體無法支撐公共RDD資料完全存放的時候,就優先考慮,使用序列化的方式在純記憶體中存儲。将RDD的每個partition的資料,序列化成一個大的位元組數組,就一個對象;序列化後,大大減少記憶體的空間占用。

序列化的方式,唯一的缺點就是,在擷取資料的時候,需要反序列化。

如果序列化純記憶體方式,還是導緻OOM,記憶體溢出;就隻能考慮磁盤的方式,記憶體+磁盤的普通方式(無序列化)。

記憶體+磁盤,序列化

第四,為了資料的高可靠性,而且記憶體充足,可以使用雙副本機制,進行持久化

持久化的雙副本機制,持久化後的一個副本,因為機器當機了,副本丢了,就還是得重新計算一次;持久化的每個資料單元,存儲一份副本,放在其他節點上面;進而進行容錯;一個副本丢了,不用重新計算,還可以使用另外一份副本。

這種方式,僅僅針對你的記憶體資源極度充足

持久化,很簡單,就是對RD調用 persist()方法,并傳入一個持久化級别
如果是 persist( StorageLevel.MEMORY_ONLY()),純記憶體,無序列化,那麼就可以用 cache()方法來替代
Storagelevel. MEMORY_ONLY_SER(),第二選擇
StorageLeve1. MEMORY_AND_DISK(),第三選擇
StorageLevel.DISK_ONLY(),第四選擇
StorageLevel. MEMORY_AND_DISK_SER()第五選
如果內存充足,要使用雙副本高可靠機制
選擇字尾帶2的政策
StorageLevel.MEMORY_ONLY_2()
           

繼續閱讀