1. 程式人生 > 實用技巧 >Spark 從 0 到 1 學習(6) —— Spark 記憶體管理

Spark 從 0 到 1 學習(6) —— Spark 記憶體管理

文章目錄


Spark 執行應用程式時,Spark 叢集會啟動 Driver 和 Executor 兩種 JVM程序。Driver 負責建立 SparkContext 上下文,提交任務,排程任務等。Executor 負責 task 的計算任務,並將結果返回給 Driver。同時需要為需要持久化的 RDD 提供儲存。Driver 端的記憶體管理比較簡單,這裡所說的 Spark 記憶體管理針對 Executor 端的記憶體管理。

Spark 記憶體管理分為靜態記憶體管理和統一記憶體管理。Spark1.6 之前使用的是靜態記憶體管理,Spark1.6 之後引入了統一記憶體管理。

1. 靜態記憶體管理

靜態記憶體管理中 儲存記憶體/執行記憶體和其他記憶體的大小在 Spark 應用程式執行期間均為固定的,但使用者可以在應用程式啟動前進行配置。

Spark1.6 以上版本預設使用同一記憶體管理,可以通過引數spark.memory.useLegacyMode設定為 true (預設為false) 使用靜態記憶體管理。

1.1 靜態記憶體管理分佈圖

在這裡插入圖片描述

1.2 靜態記憶體管理詳解

  • 60% 的記憶體用於 spark 的儲存。這部分記憶體中 10% 的記憶體用於預留,防止發生 OOM 異常。其他90% 的記憶體用於儲存資料。這90% 的記憶體中 20% 用於解壓縮和序列化資料,剩餘的 80% 的記憶體用於儲存 RDD 的快取資料和廣播變數。
  • 20% 的記憶體用於 spark 的 shuffle。這部分記憶體中 80% 的記憶體用於 shuffle 的聚合,其他 20% 的記憶體是預留記憶體,防止 OOM 異常。
  • 剩餘的記憶體用於 task 的計算。

2. 統一記憶體管理

統一記憶體管理與靜態記憶體管理的區別在於儲存記憶體和執行記憶體共享同一塊空間,可以相互借用對方的空間。

2.1 統一記憶體管理分佈圖

在這裡插入圖片描述

2.2 統一記憶體管理詳解

  • 總記憶體預留出300M,用於JVM自身執行。
  • 剩餘的記憶體中的 60 % 用於 spark ,其中一半用於 儲存 RDD 快取資料和廣播變數,另一半用於 shuffle聚合。
  • 剩餘的記憶體中的 40 % 用於 task 的計算。

3. reduce 中 OOM 如何處理?

  1. 減少每次拉取的資料量
  2. 提高 shuffle 聚合的記憶體比例
  3. 提高 Executor 的總記憶體