spark內存管理說明

spark內存有幾種不同的用途,理解並調優spark的內存使用方法有利於幫助優化spark的應用。在各個執行器中,內存有如下幾種用途。

1.RDD存儲

    當調用persist或cache方法時,這個RDD的分區會被存儲到緩存區中。spark會根據spark.storage.memoryFraction限制用來緩存的內存佔整個jvm堆空間的大小。如果超出限制,舊的分區數據會被移出內存。

2.數據混洗與聚合的緩存區

      當進行數據混洗操作時,spark會創建出一些中間緩存區來存儲數據混洗輸出的數據。這些緩存區用來存儲聚合操作的中間結果,以及數據混洗操作中直接輸出的緩存數據。spark會根據spark.shuffle.memoryFraction限定這種緩存區內存佔總內存的比例。

3.用戶代碼

spark可以執行任意的用戶代碼,故用戶的函數可以自行申請大量內存。用戶代碼可以訪問jvm堆空間中除分配給RDD存儲和數據混洗存儲以外的全部剩餘空間。

 

        在默認情況下,Spark 會使用 60%的空間來存儲 RDD,20% 存儲數據混洗操作產生的數 據,剩下的 20% 留給用戶程序。用戶可以自行調節這些選項來追求更好的性能表現。如果 用戶代碼中分配了大量的對象,那麼降低 RDD 存儲和數據混洗存儲所佔用的空間可以有 效避免程序內存不足的情況。

       除了調整內存各區域比例,我們還可以爲一些工作負載改進緩存行爲的某些要素。Spark默認的 cache() 操作會以 MEMORY_ONLY 的存儲等級持久化數據。這意味着如果緩存新的RDD 分區時空間不夠,舊的分區就會直接被刪除。當用到這些分區數據時,再進行重算。 所以有時以 MEMORY_AND_DISK 的存儲等級調用 persist() 方法會獲得更好的效果,因爲在這 種存儲等級下,內存中放不下的舊分區會被寫入磁盤,當再次需要用到的時候再從磁盤上 讀取回來。這樣的代價有可能比重算各分區要低很多,也可以帶來更穩定的性能表現。當RDD 分區的重算代價很大(比如從數據庫中讀取數據)時,這種設置尤其有用。

     對於默認緩存策略的另一個改進是緩存序列化後的對象而非直接緩存。我們可以通過MEMORY_ONLY_SER 或者 MEMORY_AND_DISK_SER 的存儲等級來實現這一點。緩存序列化後的對 象會使緩存過程變慢,因爲序列化對象也會消耗一些代價,不過這可以顯著減少 JVM 的 垃圾回收時間,因爲很多獨立的記錄現在可以作爲單個序列化的緩存而存儲。垃圾回收的 代價與堆裏的對象數目相關,而不是和數據的字節數相關。這種緩存方式會把大量對象序 列化爲一個巨大的緩存區對象。如果你需要以對象的形式緩存大量數據(比如數 GB 的數 據),或者是注意到了長時間的垃圾回收暫停,可以考慮配置這個選項。這些暫停時間可 以在應用用戶界面中顯示的每個任務的垃圾回收時間那一欄看到。

 

    

 

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