跳至內容

如何解決 Amazon EMR 上 Spark 中的 "Container killed on request.Exit code is 137" 錯誤?

2 分的閱讀內容
0

我在 Amazon EMR 上的 Apache Spark 作業失敗,並顯示 "Container killed on request.Exit code is 137" 錯誤。

簡短說明

當容器 (Spark 執行程序) 記憶體耗盡時,YARN 會自動終止該容器,您可能會收到以下錯誤:
"Container killed on request" stage failure: Caused by: org.apache.spark.SparkException: Job aborted due to stage failure: Task 2 in stage 3.0 failed 4 times, most recent failure: Lost task 2.3 in stage 3.0 (TID 23, ip-###-###-##-###.compute.internal, executor 4): ExecutorLostFailure (executor 4 exited caused by one of the running tasks) Reason: Container marked as failed: container_1516900607498_6585_01_000008 on host: ip-###-###-##-###.compute.internal.Exit status: 137.Diagnostics: Container killed on request.Exit code is 137"

解決方法

增加驅動程式或執行程式記憶體

若要增加容器記憶體,請先 連線至叢集主節點,然後修改 Spark 組態檔 (spark-defaults.conf) 中的 spark.executor.memoryspark.driver.memory 參數。

執行中的叢集

若要打開 spark-defaults.conf,請執行以下命令:

sudo vim /etc/spark/conf/spark-defaults.conf

若要增加容器記憶體,請在 spark-defaults.conf 中新增或修改以下參數:

spark.executor.memory 10g
spark.driver.memory 10g

**注意:**根據叢集可用資源與工作負載需求,將 10g 替換為記憶體值。

單一作業

當您執行 spark-submit 時,請使用 --executor-memory--driver-memory 選項來增加記憶體。

範例:

spark-submit
  --executor-memory 10g
  --driver-memory 10g
  ...

**注意:**根據叢集可用資源與工作負載需求,將 10g 替換為適當的記憶體值。

新增更多 Spark 分割區

如果無法增加容器記憶體,例如在節點上使用 maximizeResourceAllocation 來增加 Spark 分割區數量。這會降低單一 Spark 任務處理的資料量,以及單一執行程式使用的總記憶體。

若要新增 Spark 分割區,請先連線至叢集主節點,然後在 Spark shell 中執行以下命令:

val numPartitions = 500
val newDF = df.repartition(numPartitions)

**注意:**根據資料大小,將 500 替換為適當的分割區數量。

增加隨機分割區的數量

如果錯誤發生在寬幅轉換,例如 joingroupBy,請先 connect to the primary node of your cluster,然後增加隨機分割區數。預設值為 200。

執行中的叢集

若要打開 spark-defaults.conf,請執行以下命令:

sudo vim /etc/spark/conf/spark-defaults.conf

在組態檔中更新隨機分割區數:

spark.sql.shuffle.partitions 500

**注意:**根據資料大小,將 500 替換為適當的分割區數量。

單一作業

當您執行 spark-submit 時,使用 --conf spark.sql.shuffle.partitions 選項來增加隨機分割區數。

範例:

spark-submit
  --conf
  spark.sql.shuffle.partitions=500
  ...

減少執行程式核心數

當您減少執行程式核心數時,也會降低執行程式同時處理任務的最大數量。這會降低容器使用的記憶體量。

執行中的叢集

連線至叢集主節點,然後在主節點打開 spark-defaults.conf 檔案:

sudo vim /etc/spark/conf/spark-defaults.conf

若要設定執行程式核心數,請修改 spark.executor.cores 參數:

spark.executor.cores  1

**注意:**根據您的使用案例,將 1 替換為所需執行程式核心數。

單一作業

執行 spark-submit 時,使用 --executor-cores 選項來減少執行程式核心數。

範例:

spark-submit
   --executor-cores 1
   ...

增加執行個體大小

當作業系統記憶體耗盡時,作業系統 oom_reaper 也可能會終止 YARN 容器。若錯誤是由此造成,請使用具有更多 RAM 的較大執行個體。為確保 YARN 容器不會耗盡 Amazon Elastic Compute Cloud (Amazon EC2) 的記憶體,請降低 yarn.nodemanager.resource.memory-mb

檢查 Amazon EMR 執行個體日誌中的 dmesg 命令輸出結果,以判斷錯誤是否由 oom_reaper 造成。首先,使用 YARN Resource Manager UI 或日誌找到已終止的 YARN 容器所在的核心或任務節點。然後,檢查該節點在容器終止前後的 Amazon EMR 執行個體狀態日誌,以確定是否由 oom_reaper 終止該程序。

在以下範例中,核心 (Linux 的 OOM 終止程式) 會終止對應於 YARN container_165487060318_0001_01_000244,ID 為 36787 的程序:

# hows the kernel lookingdmesg | tail -n 25

[ 3910.032284] Out of memory: Kill process 36787 (java) score 96 or sacrifice child
[ 3910.043627] Killed process 36787 (java) total-vm:15864568kB, anon-rss:13876204kB, file-rss:0kB, shmem-rss:0kB
[ 3910.748373] oom_reaper: reaped process 36787 (java), now anon-rss:0kB, file-rss:0kB, shmem-rss:0kB

檢查磁碟使用率與節點降級情況

如果上述疑難排解選項無法解決錯誤,請檢查磁碟使用率及節點降級情況。在執行個體狀態日誌中使用 df-h 旗標,以檢查叢集與節點的磁碟使用情況。也請檢查 Amazon Health 儀表板 上的節點狀態。

相關資訊

如何解決 Amazon EMR 上 Spark 中的錯誤 "Container killed by YARN for exceeding memory limits"?

如何對 Amazon EMR 上 Spark 作業的階段失敗進行疑難排解?

AWS 官方已更新 5 個月前