AWS Glue 작업이 “종료 코드 1로 인한 명령 실패”를 나타내며 실패합니다. Amazon CloudWatch Logs에는 "java.lang.OutOfMemoryError: Java 힙 공간" 오류가 표시됩니다.
간략한 설명
"java.lang.OutOfMemoryError: “Java 힙 공간” 오류는 드라이버 또는 실행기에 JVM 메모리가 부족함을 나타냅니다. 드라이버 또는 실행기가 OOM을 발생시키는지 확인하려면 OOM 예외 및 작업 이상 디버깅을 참조하십시오.
참고: 다음 해결 방법은 드라이버 OOM 예외에만 해당됩니다.
드라이버 OOM 예외는 다음과 같은 이유로 발생합니다.
- AWS Glue Spark 작업은 Amazon Simple Storage Service(S3)에서 많은 수의 작은 파일을 읽습니다.
- collect(), 브로드캐스트 조인 및 공유 변수와 같은 드라이버 집약적인 작업
해결 방법
많은 수의 작은 파일로 인한 드라이버 OOM 예외 해결
DynamicFrames를 사용하는 많은 수의 작은 파일로 인해 발생하는 드라이버 OOM 예외를 해결하려면 다음 방법 중 하나 이상을 사용하십시오.
useS3ListImplementation 활성화
파일을 나열할 때 AWS Glue는 드라이버 메모리 목록에 파일 인덱스를 생성합니다. UseS3ListImplementation을 True로 설정하면 AWS Glue는 메모리의 파일 목록을 한 번에 모두 캐시하지 않습니다. 대신 AWS Glue는 목록을 일괄적으로 캐시합니다. 이것은 드라이버의 메모리가 부족할 가능성이 적다는 것을 의미합니다.
from_catalog를 사용하여 useS3ListImplementation을 활성화하는 방법에 대해서는 다음 예제를 참조하십시오.
datasource0 = glueContext.create_dynamic_frame.from_catalog(database = "database", table_name = "table", additional_options = {'useS3ListImplementation': True}, transformation_ctx = "datasource0")
from_options를 사용하여 useS3ListImplementation을 활성화하는 다음 예제를 참조하십시오.
datasource0 = glueContext.create_dynamic_frame.from_options(connection_type="s3", connection_options = {"paths": ["s3://input_path"], "useS3ListImplementation":True,"recurse":True}, format="json")
useS3ListImplementation 기능은 Amazon S3 ListKeys 작업을 구현한 것입니다. 이렇게 하면 큰 결과 집합이 여러 응답으로 분할됩니다. useS3ListImplementation에서 작업 북마크를 사용하는 것이 가장 좋습니다.
그룹화
Spark 애플리케이션은 다른 Spark 작업을 사용하여 모든 작은 파일을 처리합니다. 이로 인해 드라이버가 위치 및 태스크 정보를 저장하고 추적하기 때문에 OOM으로 이어질 수 있습니다. 그룹화 기능을 활성화하면 태스크가 개별 파일 대신 여러 파일 그룹을 처리합니다. 그룹화는 동적 프레임을 사용할 때와 Amazon S3 데이터 세트에 50,000개 이상의 파일이 있을 때 자동으로 켜집니다. 자세한 내용은 대규모 그룹에서 입력 파일 읽기를 참조하십시오.
푸시다운 조건자를 사용한 필터링
푸시다운 조건자를 사용하여 AWS Glue 작업에서 읽는 Amazon S3 파일 및 Amazon S3 파티션의 수를 줄이십시오. 이렇게 하면 기본 데이터를 읽기 전에 AWS Glue 테이블에서 불필요한 파티션이 제거됩니다. 자세한 내용은 푸시다운 조건자를 사용한 사전 필터링을 참조하십시오.
드라이버의 과도 작업으로 인한 드라이버 OOM 예외
다음 방법 중 하나를 사용하여 드라이버의 과도 작업으로 인해 발생하는 드라이버 OOM 예외를 해결하십시오.
드라이버 집약적 작업에 유의
**collect()**는 작업자로부터 결과를 수집한 다음, 이를 드라이버에 단일 객체로 반환하는 Spark 연산입니다. 결과는 매우 커질 수 있으며 이로 인해 드라이버에 과부하가 걸립니다. 기본적으로 Spark 구성인 Spark.Driver.MaxResultSize는 1GB로 설정되며, 드라이버에 과부하가 걸리지 않도록 보호하는 데 도움이 됩니다.
따라서 이러한 작업을 제한하고 가능하면 take(), takeSample() 또는 **isEmpty()**와 같은 작업을 대신 사용하십시오.
또한 관계(테이블)가 드라이버의 사용 가능한 메모리보다 클 경우 Spark에서 브로드캐스트 조인으로 인해 OOM 오류가 발생할 수 있다는 점에 유의하십시오. 관계가 실행기로 브로드캐스트되기 전에 드라이버 노드에서 구체화됩니다. 여러 테이블을 브로드캐스트하거나 관계가 너무 크면 드라이버에 메모리 부족이 발생할 수 있습니다. Spark 구성 spark.sql.autoBroadcastJoinThreshold 및 Spark 작업 힌트를 사용하여 이 문제를 제어합니다.
공유 변수 정기적으로 폐기
공유 변수는 주의해서 사용해야 합니다. 공유 변수는 Spark 드라이버 OOM 예외를 유발할 수 있으므로 더 이상 필요하지 않는 경우 폐기하십시오. 공유 변수에는 브로드캐스트 변수와 누적기의 두 가지 유형이 있습니다.
- 브로드캐스트 변수는 실행기에 한 번만 전송되는 읽기 전용 데이터입니다. 모든 실행기 간에 공유되는 작은 사전이나 작은 테이블과 같은 변경할 수 없는 참조 데이터를 저장하는 데 적합한 솔루션입니다.
- 누적기는 Spark 실행기 전체에 쓰기 가능한 복사본을 제공하며, 분산 카운터(예: MapReduce) 또는 합계를 구현하는 데 사용할 수 있습니다.
추가 문제 해결
관련 정보
AWS Glue의 메모리 관리 최적화
대규모 그룹에서 입력 파일 읽기
Amazon EMR에서 Apache Spark 애플리케이션의 메모리를 성공적으로 관리하기 위한 모범 사례
Apache Spark 웹 UI를 사용하여 작업 모니터링