當第一次對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,記憶體溢位;就只能考慮磁碟的方式,記憶體+磁碟的普通方式(無序列化)。記憶體+磁碟,序列化。
第四,為了資料的高可靠性,而且記憶體充足,可以使用雙副本機制,進行持久化
持久化的雙副本機制,持久化後的乙個副本,因為機器宕機了,副本丟了,就還是得重新計算一次;持久化的每個資料單元,儲存乙份副本,放在其他節點上面;從而進行容錯;乙個副本丟了,不用重新計算,還可以使用另外乙份副本。這種方式,僅僅針對你的記憶體資源極度充足。
sessionid2actionrdd = sessionid2actionrdd.persist(storagelevel.memory_only());
/*** 持久化,很簡單,就是對rdd呼叫persist()方法,並傳入乙個持久化級別
* * 如果是persist(storagelevel.memory_only()),純記憶體,無序列化,那麼就可以用cache()方法來替代
* storagelevel.memory_only_ser(),第二選擇
* storagelevel.memory_and_disk(),第三選擇
* storagelevel.memory_and_disk_ser(),第四選擇
* storagelevel.disk_only(),第五選擇
* * 如果記憶體充足,要使用雙副本高可靠機制
* 選擇字尾帶_2的策略
* storagelevel.memory_only_2()
* */
sessionid2actionrdd = sessionid2actionrdd.persist(storagelevel.memory_only());
spark效能調優 RDD持久化
第一,rdd重構與優化 盡量去復用rdd,差不多的rdd,可以抽取成為乙個共同的rdd,供後面的rdd計算時,反覆使用。第二,公共rdd一定要實現持久化 持久化,也就是說,將rdd中的資料快取到記憶體中,或者快取到磁碟中,blockmanager 以後無論對這個rdd做多少次計算,那麼都是直接取rd...
二 Spark效能調優 RDD優化
在對 rdd 進行運算元時,要避免相同的運算元和計算邏輯之下對 rdd 進行重複的計算,優化前如圖 優化後如圖 在 spark 中,當多次對同乙個 rdd 執行運算元操作時,每一次都會對這個 rdd以之前的父 rdd 重新計算一次,這種情況是必須要避免的,對同乙個 rdd 的重複計算是對資源的極大浪...
技術難點 Spark效能調優 RDD運算元調優篇
不廢話,直接進入正題!1.rdd復用 在對rdd進行運算元時,要避免相同的運算元和計算邏輯之下對rdd進行重複的計算,如下圖所示 對上圖中的rdd計算架構進行修改,得到如下圖所示的優化結果 2.盡早filter 獲取到初始rdd後,應該考慮盡早地過濾掉不需要的資料,進而減少對記憶體的占用,從而提公升...