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

2 分的閱讀內容
0

我在 Amazon EMR 上的 Apache Spark 工作失敗,因為 "Container killed on request" 階段失敗: 造成的原因是:org.apache.spark.SparkException: 工作因階段失敗而中止: 階段 3.0 中的任務 2 失敗了 4 次,最近的失敗: 在階段 3.0 中遺失了任務 2.3 (TID 23, ip-xxx-xxx-xx-xxx.compute.internal, executor 4): ExecutorLostFailure (執行中的一項任務造成執行程式 4 結束) 原因: 標記為失敗的容器:主機上的 container_1516900607498_6585_01_000008: ip-xxx-xxx-xx-xxx.compute.internal。結束狀態: 137。診斷: 容器應要求被終止。結束代碼為 137

簡短描述

當容器 (Spark 執行程序) 用盡記憶體時,YARN 會自動終止它。這會導致 "Container killed on request.Exit code is 137" 錯誤。這些錯誤可能會在不同的工作階段發生,無論是在窄幅或寬幅轉換中。當作業系統用盡記憶體時,YARN 容器也可能被 OS oom_reaper 終止,導致 "Container killed on request.Exit code is 137" 錯誤。

解決方法

使用下列一個或多個方法來解決 "Exit status: 137" 階段失敗。

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

調整 spark.executor.memoryspark.driver.memory 參數 (取決於造成錯誤的容器) 來增加容器記憶體。

在執行中的叢集上:

修改主節點上的 spark-defaults.conf。範例:

sudo vim /etc/spark/conf/spark-defaults.conf
spark.executor.memory 10g
spark.driver.memory 10g

對於單一工作:

執行 spark-submit 時使用 --executor-memory--driver-memory 選項增加記憶體。範例:

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

新增更多 Spark 分割區

如果無法增加容器記憶體 (例如,如果您在節點上使用 maximizeResourceAllocation),則增加 Spark 分割區的數量。這樣可減少單一 Spark 任務處理的資料量,並減少單一執行程式使用的總記憶體。使用下面的 Scala 代碼新增更多的 Spark 分割區:

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

增加隨機分區的數量

如果在寬幅轉換 (例如 joingroupBy) 期間發生錯誤,請新增更多隨機分割區。預設值為 200。

在執行中的叢集上:

修改主節點上的 spark-defaults.conf。範例:

sudo vim /etc/spark/conf/spark-defaults.conf
spark.sql.shuffle.partitions 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  1

對於單一工作:

執行 spark-submit 時,使用 --executor-core 選項減少執行程式內核的數量。範例:

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

增加執行個體大小

當作業系統用盡記憶體時,YARN 容器也可能被 OS oom_reaper 終止。如果此錯誤的發生是 oom_reaper 所致,請使用具有更多 RAM 的更大執行個體。您也可以降低 yarn.nodemanager.resource.memory-mb 以防止 YARN 容器用盡 Amazon EC2 的所有 RAM。

您可以檢視 dmesg 命令輸出的 Amazon EMR 執行個體日誌來偵測錯誤是否為 oom_reaper 所致。首先找到已終止的 YARN 容器正在執行的內核或任務節點。您可以使用 YARN Resource Manager UI 或日誌找到此資訊。然後,檢查此節點上在容器被終止前後的 Amazon EMR 執行個體狀態日誌,以查看是什麼終止了該處理程序。

在下列範例中,ID 為 36787、對應於 YARN container_165487060318_0001_01_000244 的處理程序被內核 (Linux 的 OOM 終止程式) 終止:

# hows the kernel looking
dmesg | 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

相關資訊

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

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

AWS 官方
AWS 官方已更新 2 年前