Amazon EMR에서 Apache Spark 작업이 "Container killed on request. Exit code is 137" 오류와 함께 실패합니다.
간략한 설명
컨테이너(Spark 실행기)의 메모리가 부족하면 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 구성 파일(spark-defaults.conf)의 spark.executor.memory 또는 spark.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 셸에서 다음 명령을 실행합니다.
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
...
실행기 코어의 수 줄이기
실행기 코어의 수를 줄이면 실행기가 동시에 처리하는 최대 작업 수도 감소합니다. 이렇게 하면 컨테이너에서 사용하는 메모리 양이 줄어듭니다.
실행 중인 클러스터
먼저 클러스터의 프라이머리 노드에 연결한 다음 프라이머리 노드에서 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 컨테이너를 종료할 수도 있습니다. 이로 인해 오류가 발생하면 RAM 용량이 더 큰 대규모 인스턴스를 사용하십시오. YARN 컨테이너가 Amazon Elastic Compute Cloud(Amazon EC2)의 RAM을 소진하지 않도록 하려면 yarn.nodemanager.resource.memory-mb y값을 낮추십시오.
dmesg 명령 출력에서 Amazon EMR 인스턴스 로그를 검토하여 oom_reaper가 오류를 유발하는지 확인하십시오. 먼저 YARM Resource Manger UI 또는 로그를 사용하여 종료된 YARN 컨테이너가 실행한 코어 또는 태스크 노드를 찾습니다. 그런 다음 컨테이너가 종료되기 전과 후에 이 노드의 Amazon EMR 인스턴스 상태 로그를 확인하여 oom_reaper로 인해 프로세스가 종료되었는지 확인합니다.
다음 예제에서는 YARN container_165487060318_0001_01_000244에 해당하는 ID 36787의 프로세스가 커널(Linux OOM이 종료된 원인)에 의해 종료되었습니다.
# 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 Dashboard에서 노드 상태를 확인하십시오.
관련 정보
Amazon EMR의 Spark에서 "Container killed by YARN for exceeding memory limits" 오류를 해결하려면 어떻게 해야 합니까?
Amazon EMR에서 Spark 작업의 스테이지 실패 문제를 해결하려면 어떻게 해야 합니까?