대규모 데이터 세트를 Amazon RDS에서 Amazon S3로 마이그레이션할 때 노드 손실로 인해 AWS Glue 작업이 실패하는 이유는 무엇입니까?

최종 업데이트 날짜: 2022년 9월 19일

AWS Glue를 사용하여 Amazon Relational Database Service(RDS) 또는 온프레미스 JDBC 데이터베이스에서 Amazon Simple Storage Service(S3)로 대규모 데이터 세트를 마이그레이션하고 있습니다. 그런데 ETL 작업이 오랫동안 실행된 후 노드 손실로 인해 실패합니다.

간략한 설명

AWS Glue는 하나의 연결을 사용하여 전체 데이터 세트를 읽습니다. 대규모 JDBC 테이블을 마이그레이션하는 경우 AWS Glue 측에서 진행 중임을 알 수 없는 상태로 ETL 작업이 오래 실행될 수 있습니다. 결국 디스크 공간 문제로 작업에 실패할 수 있습니다(손실된 노드). 이 문제를 해결하려면 JDBC 테이블을 병렬로 읽습니다. 손실된 노드로 작업이 계속 실패하는 경우 SQL 표현식을 pushdown 조건자로 사용합니다.

​해결 방법

다음 방법 중 하나 이상을 사용하여 JDBC 데이터 세트에 대한 노드 손실 오류를 해결합니다.

병렬로 JDBC 테이블 읽기

테이블에 숫자 열(INT 또는 BIGINT)이 없으면 hashfield 옵션을 사용하여 데이터를 분할합니다. hashfield를 JDBC 테이블의 열 이름으로 설정합니다. 최상의 결과를 얻으려면 값이 균등하게 분산된 열을 선택합니다.

테이블에 숫자 열이 있으면 DynamicFrame을 생성하는 중에 또는 테이블에서 hashpartitionshashexpression 옵션을 설정합니다.

  • hashpartitions: AWS Glue가 데이터를 읽기 위해 생성하는 작업 수 정의
  • hashexpression: 태스크 사이에서 균등하게 행 구분

다음은 JDBC 연결을 사용하여 DynamicFrame을 생성하는 중에 hashpartitionshashexpression을 설정하는 방법에 대한 예제입니다. connection_option에서 JDBC URL, 사용자 이름, 암호, 테이블 이름 및 열 이름을 바꿉니다.

connection_option= {"url": "jdbc:mysql://mysql–instance1.123456789012.us-east-1.rds.amazonaws.com:3306/database", "user": "your_user_name", "password": "your_password","dbtable": "your_table","hashexpression":"column_name","hashpartitions":"10"}

datasource0 = glueContext.create_dynamic_frame.from_options('mysql',connection_options=connection_option,transformation_ctx = "datasource0")

다음은 AWS Glue 카탈로그에서 DynamicFrame을 생성하는 중에 hashpartitionshashexpression을 설정하는 방법에 대한 예제입니다.

datasource0 = glueContext.create_dynamic_frame.from_catalog(database = "your_database", table_name = "your_table",additional_options={"hashexpression":"column_name","hashpartitions":"10"}, transformation_ctx = "datasource0")

참고: hashpartitions에 대해 더 큰 값을 설정하면 테이블 성능이 떨어질 수 있습니다. 각 태스크가 전체 테이블을 읽은 후 실행기로 행 세트를 반환하기 때문입니다.

자세한 내용은 JDBC 테이블을 병렬로 읽기를 참조하세요.

pushdown 조건자로서 SQL 표현식 사용

참고: 다음 SQL 표현식은 Oracle 데이터베이스의 pushdown 조건자로 작동하지 않습니다. 하지만 표현식은 AWS Glue(Amazon Aurora, MariaDB, Microsoft SQL Server, MySQL 및 PostgreSQL)에서 기본적으로 지원되는 다른 모든 데이터베이스의 pushdown 조건자로 작동합니다.

테이블에 수십억 개의 레코드와 테비바이트(TiB)의 데이터가 포함된 경우 hashpartitionshashexpression을 설정한 후에도 손실된 노드로 작업이 실패하거나 작업을 완료하는 데 오래 걸릴 수 있습니다. 이 문제를 해결하려면 hashexpression 옵션과 함께 다음과 유사한 SQL 표현식을 사용합니다.

column_name > 1000 AND column_name < 2000 AND column_name

SQL 표현식은 pushdown 조건자 역할을 하며 한 번에 모든 데이터를 읽는 대신, 작업을 실행할 때마다 작업이 행의 한 세트를 읽도록 강제로 구성합니다. 전체 문은 다음과 유사합니다.

datasource0 = glueContext.create_dynamic_frame.from_catalog(database = "sampledb", table_name = "test_table",additional_options={"hashexpression":"column_name > 1000 AND column_name < 2000 AND column_name","hashpartitions":"10"}, transformation_ctx = "datasource0")

참고: 이 구성으로 작업을 처음 실행하는 경우 작업 북마크를 꺼야 합니다. 작업 북마크와 함께 작업을 실행하면 AWS Glue는 열의 최대값을 기록합니다. 작업을 다시 실행하면 AWS Glue는 이전 북마크 값보다 값이 더 큰 행만 처리합니다. 필요에 따라 마지막 작업 실행 중에 작업 북마크를 켤 수 있습니다.