Amazon EMR의 Spark에서 ‘Container killed by YARN for exceeding memory limits’ 오류를 해결하고 싶습니다.
간략한 설명
이 오류를 해결하려면 다음 방법 중 하나를 사용하십시오.
- 메모리 오버헤드를 늘립니다.
- 실행기 코어의 수를 줄입니다.
- 파티션 수를 늘립니다.
- 드라이버 및 실행기 메모리를 늘립니다.
해결 방법
이 오류의 근본 원인과 적절한 해결책은 워크로드에 따라 다릅니다. 오류를 해결하려면 다음 각 방법을 순서대로 시도해야 할 수도 있습니다. 이 순서의 다음 방법으로 진행하기 전에 이전 섹션에서 spark-defaults.conf에 변경한 내용을 모두 취소하십시오.
메모리 오버헤드 늘리기
메모리 오버헤드는 각 실행기에 할당된 오프 힙 메모리의 양입니다. 기본적으로 메모리 오버헤드는 실행기 메모리의 10% 또는 384 중 더 높은 값으로 설정됩니다. 메모리 오버헤드는 Java NIO 다이렉트 버퍼, 스레드 스택, 공유 네이티브 라이브러리 또는 메모리 매핑 파일에 사용됩니다.
메모리 오버헤드를 최대 25%까지 점진적으로 늘리는 것을 고려해 보십시오. 드라이버 또는 실행기 메모리와 메모리 오버헤드의 합계는 인스턴스 유형의 yarn.nodemanager.resource.memory-mb보다 작아야 합니다.
spark.driver/executor.memory + spark.driver/executor.memoryOverhead < yarn.nodemanager.resource.memory-mb
드라이버 컨테이너나 실행기 컨테이너에서 오류가 발생하는 경우 해당 컨테이너의 메모리 오버헤드만 늘리는 것이 좋습니다. 클러스터를 실행하는 동안, 새 클러스터를 시작할 때 또는 작업을 제출할 때 메모리 오버헤드를 늘릴 수 있습니다.
실행 중인 클러스터에서:
마스터 노드에서 spark-defaults.conf를 수정합니다.
예를 들면 다음과 같습니다.
sudo vim /etc/spark/conf/spark-defaults.conf
spark.driver.memoryOverhead 512
spark.executor.memoryOverhead 512
새 클러스터에서:
클러스터를 시작할 때 다음과 비슷한 구성 객체를 추가합니다.
[
{
"Classification": "spark-defaults",
"Properties": {
"spark.driver.memoryOverhead": "512",
"spark.executor.memoryOverhead": "512"
}
}
]
단일 작업의 경우:
spark-submit 실행 시 메모리 오버헤드를 늘리려면 --conf 옵션을 사용합니다.
예를 들면 다음과 같습니다.
spark-submit --class org.apache.spark.examples.SparkPi --master yarn --deploy-mode cluster --conf spark.driver.memoryOverhead=512 --conf spark.executor.memoryOverhead=512 /usr/lib/spark/examples/jars/spark-examples.jar 100
메모리 오버헤드를 늘려도 문제가 해결되지 않으면 실행기 코어의 수를 줄이십시오.
실행기 코어의 수 줄이기
이렇게 하면 실행기에서 수행할 수 있는 최대 작업 수가 줄어들어 필요한 메모리 양이 줄어듭니다. 이 오류를 발생시키는 드라이버 컨테이너 또는 이 오류가 발생하는 다른 실행기 컨테이너에 따라 드라이버 또는 실행기의 코어를 줄이는 것이 좋습니다.
실행 중인 클러스터에서:
마스터 노드에서 spark-defaults.conf를 수정합니다.
예를 들면 다음과 같습니다.
sudo vim /etc/spark/conf/spark-defaults.conf
spark.driver.cores 3
spark.executor.cores 3
새 클러스터에서:
클러스터를 시작할 때 다음과 비슷한 구성 객체를 추가합니다.
[
{
"Classification": "spark-defaults",
"Properties": {"spark.driver.cores" : "3",
"spark.executor.cores": "3"
}
}
]
단일 작업의 경우:
spark-submit을 실행할 때 --executor-cores 옵션을 사용하여 실행기 코어의 수를 줄입니다.
예를 들면 다음과 같습니다.
spark-submit --class org.apache.spark.examples.SparkPi --master yarn --deploy-mode cluster --executor-cores 3 --driver-cores 3 /usr/lib/spark/examples/jars/spark-examples.jar 100
여전히 오류 메시지가 표시되면 파티션 수를 늘리십시오.
파티션 수 늘리기
파티션 수를 늘리려면 원시 복원력 분산 데이터세트의 spark.default.parallelism 값을 늘리거나 .repartition() 작업을 실행하십시오. 파티션 수를 늘리면 파티션당 필요한 메모리 양이 줄어듭니다. Spark는 속도를 극대화하는 효과적인 방법으로 클러스터 RAM을 많이 사용합니다. 따라서 Ganglia로 메모리 사용량을 모니터링한 다음, 클러스터 설정과 파티셔닝 전략이 증가하는 데이터 요구 사항을 충족하는지 확인해야 합니다. ‘Container killed by YARN for exceeding memory limits’ 오류 메시지가 계속 표시되면 드라이버와 실행기 메모리를 늘리십시오.
드라이버 및 실행기 메모리 늘리기
오류가 드라이버 컨테이너나 실행기 컨테이너에서 발생하는 경우, 드라이버 또는 실행기 중 하나의 메모리를 늘리는 것을 고려하되 둘 다 늘리지 않는 것이 좋습니다. 드라이버 또는 실행기 메모리와 드라이버 또는 실행기 메모리 오버헤드의 합계가 항상 EC2 인스턴스 유형의 yarn.nodemanager.resource.memory-mb 값보다 작아야 합니다.
spark.driver/executor.memory + spark.driver/executor.memoryOverhead < yarn.nodemanager.resource.memory-mb
실행 중인 클러스터에서:
마스터 노드에서 spark-defaults.conf를 수정합니다.
예:
sudo vim /etc/spark/conf/spark-defaults.conf
spark.executor.memory 1g
spark.driver.memory 1g
새 클러스터에서:
클러스터를 시작할 때 다음과 비슷한 구성 객체를 추가합니다.
[
{
"Classification": "spark-defaults",
"Properties": {
"spark.executor.memory": "1g",
"spark.driver.memory":"1g",
}
}
]
단일 작업의 경우:
spark-submit을 실행할 때 --executor-memory 또는 --driver-memory 옵션을 사용하여 메모리를 늘립니다.
예를 들면 다음과 같습니다.
spark-submit --class org.apache.spark.examples.SparkPi --master yarn --deploy-mode cluster --executor-memory 1g --driver-memory 1g /usr/lib/spark/examples/jars/spark-examples.jar 100
기타 해결책 옵션
여전히 오류 메시지가 표시되면 다음을 시도해 보십시오.
- 벤치마킹: 샘플 데이터세트를 대상으로 애플리케이션을 실행하는 것이 가장 좋습니다. 이렇게 하면 메모리 문제를 일으킬 수 있는 속도 저하와 편차 파티션을 파악내는 데 도움이 될 수 있습니다.
- 데이터 필터링: 최소한의 데이터를 처리하고 있는지 확인하십시오. 데이터를 필터링하지 않거나 애플리케이션 실행 후 늦게 필터링하는 경우 과도한 데이터로 인해 애플리케이션 속도가 느려질 수 있습니다. 이에 따라 메모리 예외가 발생할 가능성이 높아질 수 있습니다.
- 데이터세트 크기: 필요한 최소 데이터를 처리하는 것이 가장 좋습니다. 필요한 데이터만 수집되도록 데이터를 분할합니다.
- 파티셔닝 전략: 다른 파티셔닝 전략을 사용하는 것을 고려해 보십시오. 예를 들어, 큰 파티션 및 편차 파티션을 방지하도록 대체 키로 분할합니다.
- EC2 인스턴스 유형: EC2 인스턴스에는 워크로드에 필요한 메모리 리소스가 없을 수 있습니다. 더 큰 메모리 최적화 인스턴스 유형으로 전환하면 오류가 해결될 수 있습니다. 인스턴스 유형을 변경한 후에도 메모리 예외가 계속 발생하면 새 인스턴스에서 문제 해결 방법을 시도해 보십시오.
관련 정보
Spark 구성
Amazon EMR의 Spark에서 ‘java.lang.ClassNotFoundException’을 해결하려면 어떻게 해야 합니까?