Amazon EMR에서 Apache Spark 작업이 실패하고 "Container killed on request. Exit code is 137" 오류가 표시됩니다.
간략한 설명
컨테이너의 메모리가 부족하면 YARN이 자동으로 컨테이너를 종료하며 다음과 같은 오류 메시지가 표시될 수 있습니다.
"Container killed on request" 스테이지 실패: 원인: org.apache.spark.SparkException: 스테이지 실패로 인해 작업이 중단되었습니다. 스테이지 3.0의 태스크 2가 4번 실패했습니다. 가장 최근의 실패는 다음과 같습니다. Lost task 2.3 in stage 3.0 (TID 23, ip-###-###-##-###.compute.internal, executor 4): ExecutorLostFailure(실행 중인 태스크 중 하나로 인해 실행기 4 종료) 이유: 실패한 것으로 표시된 컨테이너: container_1516900607498_6585_01_000008 on host: ip-###-###-##-###.compute.internal. 종료 상태: 137. 진단: 요청 시 컨테이너가 종료되었습니다. 종료 코드는 137입니다.
해결 방법
드라이버 또는 컨테이너 메모리 늘리기
실행 중인 클러스터 또는 단일 작업의 컨테이너 메모리를 늘리려면 먼저 클러스터의 프라이머리 노드를 연결합니다. 그런 다음 spark-defaults.conf Spark 구성 파일에서 spark.executor.memory 또는 spark.driver.memory 파라미터를 수정합니다.
실행 중인 클러스터
spark-defaults.conf를 열려면 다음 명령을 실행합니다.
sudo vim /etc/spark/conf/spark-defaults.conf
컨테이너 메모리를 늘리려면 spark-defaults.conf에서 spark.executor.memory 또는 spark.driver.memory 파라미터를 추가하거나 수정하십시오.
spark.executor.memory 10g
spark.driver.memory 10g
참고: 10g를 클러스터의 가용 리소스 및 워크로드 요구 사항에 적합한 값으로 바꾸십시오.
단일 작업
메모리를 늘리려면 다음 spark-submit 명령을 실행할 때 --executor-memory 또는 --driver-memory 옵션을 사용하십시오.
spark-submit
--executor-memory 10g
--driver-memory 10g
...
참고: 10g를 클러스터의 가용 리소스 및 워크로드 요구 사항에 적합한 값으로 바꾸십시오.
스파크 구성 분류에서 maximizeResourceAllocation을 true로 설정할 수도 있습니다.
Spark 파티션 추가
컨테이너 메모리를 늘릴 수 없다면 Spark 파티션 수를 늘려 처리되는 데이터와 사용되는 메모리의 양을 줄이십시오.
Spark 파티션을 추가하려면 먼저 클러스터의 프라이머리 노드를 연결한 후 Spark 셸에서 다음 명령을 실행합니다.
val numPartitions = 500
val newDF = df.repartition(numPartitions)
참고: 500을 데이터 크기에 맞는 파티션 수로 바꾸십시오.
셔플 파티션의 수 늘리기
join 또는 groupBy와 같은 광범위한 변환 중에 문제가 발생하면 클러스터의 프라이머리 노드에 연결하고 셔플 파티션을 더 추가하십시오. 기본값은 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
...
참고: 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
...
인스턴스 크기 늘리기
운영 체제(OS)의 메모리가 부족하면 OS oom_reaper가 YARN 컨테이너를 중지할 수도 있습니다. oom_reaper로 인해 오류가 발생한 경우 RAM이 더 많은 대규모 Amazon Elastic Compute Cloud(Amazon EC2) 인스턴스를 사용하십시오. YARN 컨테이너가 RAM을 소진하지 않도록 하려면 yarn.nodemanager.resource.memory-mb를 줄이십시오.
oom_reaper로 인해 오류가 발생했는지 확인하려면 Amazon EMR 인스턴스 로그에서 dmesg 명령 출력을 검토하십시오. 먼저 YARM Resource Manger UI 또는 로그를 사용하여 중지된 YARN 컨테이너가 실행한 코어 또는 태스크 노드를 찾습니다. 그런 다음 컨테이너가 중지되기 전과 후에 노드에서 Amazon EMR 인스턴스 상태 로그를 확인합니다.
다음 예시에서는 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 플래그를 사용하여 디스크 사용률 및 노드 성능 저하를 확인하십시오. 또한 AWS Health Dashboard에서 노드 상태를 확인하십시오.
관련 정보
Amazon EMR의 Spark에서 "Container killed by YARN for exceeding memory limits" 오류를 해결하려면 어떻게 해야 합니까?
Amazon EMR에서 Spark 작업의 스테이지 실패 문제를 해결하려면 어떻게 해야 합니까?