spark的一大特性就是基於記憶體計算,driver只儲存任務的巨集觀性的元資料,資料量較小,且在執行過程中基本不變,不做重點分析,而真正的計算任務task分布在各個executor中,其中的記憶體資料量大,且會隨著計算的進行會發生實時變化,所以executor的記憶體管理才分析的重點。
在執行spark應用程式時,集群會啟動driver和executor兩種jvm程序,前者為主控程序,負責建立spark上下文(context),提交spark作業(job),將作業轉化為計算任務(task),在各個executor程序間協調任務的排程。後者負責在工作節點上執行具體任務,並將結果返回給driver,同時為需要持久化的rdd提供儲存功能。
作為乙個jvm程序,executor的記憶體管理時基於jvm記憶體管理機制的,spark對jvm-on-heap記憶體進行了更為詳細的規劃,以充分利用。同時spark還引入了off-heap記憶體,使之可以直接從執行節點的系統記憶體中開闢空間,進一步優化記憶體的使用。
堆記憶體的分配和**完全依賴jvm的gc機制,應用不能靈活的操作記憶體,使用堆外記憶體則可以通過os來分配和釋放,更為靈活
靜態記憶體管理:早期使用,on-heap分為四個區域,分別是storage(20%)、execution(60%)、other(20%)、ext,storage用於快取持久化的rdd資料和廣播變數等,execution用於快取shuffle過程中產生的中間資料,other區用於儲存執行中的其他物件,ext是一塊較小的預留空間,用以防止oom的發生,起到兜底作用,幾個區塊間有嚴格的界限,不可逾越。off-heap分為兩個區,storage(50%)、execution(50%),也有嚴格界限,不可逾越。記憶體的動態占用:統一記憶體管理:於spark-1.6後引入,與靜態管理機制的不同在於初始storage(50%)、execution(50%),在執行過程中兩個區域可以根據自己和對方的內粗餘量彈性的越界分配,更加靈活高效。off-heap也是兩個區域,沒有嚴格界限可以動態占用。
0.儲存 < 50% && 執行 < 50%:互不占用統一記憶體管理機制,有效的提高了堆記憶體和堆外記憶體的使用效率,降低了使用複雜度,但是並不能就此高枕無憂。由於rdd資料往往是長期生存的,如果儲存在記憶體中的資料過多,會引發頻繁的full-gc,降低了程式的吞吐量。1.儲存 > 50% && 執行 > 50%:溢寫磁碟(前提是快取級別包含磁碟,若級別為純記憶體則丟棄資料)
2.儲存 > 50% && 執行 < 50%:儲存跨界借用,若一段時間後執行記憶體不足,則刪除被借用記憶體,優先滿足執行的記憶體需要。
3.儲存 < 50% && 執行 > 50%:執行跨界借用,若一段時間後儲存記憶體不足,則不能被執行占用的儲存區記憶體,因為執行的優先順序更高,要優先保證執行資料。
Spark記憶體管理
spark記憶體用途 rdd儲存 當呼叫rdd 的persist 或cache 方法時,這個rdd 的分割槽會被儲存到快取區中。spark 會根據spark.storage.memoryfraction 限制用來快取的記憶體佔整個jvm 堆空間的 比例大小。如果超出限制,舊的分割槽資料會被移出記憶體...
Spark記憶體管理
spark記憶體管理不是通過物理或者硬體底層api實現對記憶體資源探測,只是通過對記憶體操作過程期間的位元組量的變化不斷更新維護的數字,通過該方式跟蹤記憶體使用情況。spark對每個task都關聯了記憶體的使用量,存放在了map中。嚴格意義上講,spark記憶體的管理是估算量,不是精確量。spark...
Spark 記憶體管理概述
spark被稱作記憶體計算引擎,使得很多初學者認為spark執行環境一定需要大量記憶體,更有甚者,認為spark執行期會把原始資料一次性全部載入到記憶體。解開這些疑團,需要了解spark執行時的機制,spark的計算發生在executor,因此,這裡的執行時機制是指executor的行為。對於spa...