AWS Glue로 만들어 보는 간단 배치 시스템
안녕하세요. 저는 야놀자 클라우드에서 키오스크 개발을 담당하고 있는 정원석이라고 합니다. 아래 내용은 일전에 한 프로젝트를 진행하다가 간단한 배치 시스템이 필요한 상황에서 AWS Glue를 이용해 구성한 경험을 기록한 내용입니다. 설정이 간단하고 적은 리소스로도 운영이 가능하면서도 안정적이고 대용량의 처리가 가능한 배치를 원하는 분들에게 작은 도움이 되었으면 합니다.
들어가는 말
AWS는 배치 시스템을 위해서 AWS Batch라는 정식 서비스를 제공한다. 대형 배치를 처리하기 위해서 적합한 서비스이지만 간단한 워크 플로우 조건 작업이 있는 배치를 생성하기 위해서는 생각보다 많은 준비 과정이 필요하다.
AWS Glue는 AWS에서 제공하는 서버리스 데이터 ETL 서비스이다. 데이터 처리를 위한 스크립트를 직접 Job 콘솔에서 등록할 수 있고 해당 Job을 특정 조건에서 자동으로 실행하기 위한 Trigger도 등록할 수 있다. 더 나아가 다양한 Trigger를 조합해서 실행시킬 수 있는 Workflow도 제공하고 있다. 더불어 1vCPU 단위로 구동해야 하는 AWS Batch와는 달리 최소 0.0625 DPU 단위로 구동이 가능하다. (DPU는 4개의 vCPU와 16GB의 메모리로 구성되어 있는 프로세싱 파워의 상대적 측정값이다.)
이 글에서는 AWS Glue를 데이터 ETL 서비스가 아닌 서버리스 배치 시스템으로 활용하는 방법에 대해서 소개하기로 한다.
1. Connection 추가
Job이 사용자의 Aurora에 접근할 필요가 있다면 해당 DB에 접근할 수 있도록 Network Connection을 추가해야 한다. AWS Glue > Data catalog > Databases > Connections에서 Add connection 버튼 클릭 후 Network connection을 추가해 준다.
다음 페이지에서 필요한 설정들을 추가해서 connection을 추가한다.
추가된 커넥션은 목록에서 정상적으로 연결되는지 확인해 볼 수 있다. 테스트에 1분 정도 시간이 소요될 수 있고 접근이 가능하다는 메시지를 볼 수 있으면 성공이다.
2. Job 추가
Job은 ETL 작업을 구성하는 가장 작은 작업 단위이고 Scala와 Python으로 작성할 수 있다. 여기에서는 목적에 따라 Python shell의 Python 3로 배치 스크립트를 작성한다.
AWS Glue > ETL > Jobs 페이지에서 Add job 버튼을 눌러 아래와 같이 Job을 추가해 준다.
새로운 스크립트를 추가할 예정이어서 This job runs: A new script to be authored by you
를 선택하고 스크립트의 이름과 저장 위치를 선택해 준다.
다음 페이지로 넘어가기 전에 Security configuration, script libraries, and job paramters (optional)
항목을 열어 추가 내용을 기록해 준다.
여기에서 몇 가지 주의 깊게 봐야 할 부분이 있다.
Python library path
는 Job이 실행될 때 함께 설치되는 라이브러리 경로를 지정해 주어야 한다. whl 파일로 지정할 수 있고 여러 개라면 쉼표로 구분해서 추가할 수 있다. 여기에서는 mysql connection을 사용할 예정이므로 S3에 저장한PyMySQL-0.9.3-py2.py3-none-any.whl
을 지정해 주었다. 참고로 AWS Glue 자체에서 기본 제공하는 라이브러리가 있으니 중복 설치하지 않도록 주의하자.Referenced files path
는 여러 Job에서 공용으로 사용하는 함수나 설정을 포함하는 파일을 지정할 수 있다. 여기에서는 설정 내용이 포함된 config.py 파일을 지정해 주었다. 쉼표로 구분해 복수 개의 파일을 추가할 수 있는지는 확인이 필요하다.Maximum capacity
는 DPU 단위로 기록한다. DPU는 앞서 말한대로 4개의 vCPU와 16GB의 메모리로 구성되어 있는 프로세싱 파워의 상대적 측정값이다. 디폴트는 0.0625이고 실행 시메모리 부족 등의 현상이 발생할 경우 1로 변경해서 수행한다.Max concurrency
와Job timeout
을 지정할 수도 있다. Max concurrency가 1일 경우 중복 수행 시도 시 에러가 발생한다. timeout은 분단위이며 default가 2880 분이다.Job parameter
를 추가할 수도 있는데 Job 스크립트에서getResolvedOptions
함수를 사용해 접근할 수 있다.
다음 페이지에서 Job이 사용할 Connection을 선택해 준다. 여기서는 앞서 만든 network-sample-connection
을 선택한다.
저장하면 스크립트를 편집할 수 있는 페이지가 나오는데 아래와 같이 실제 실행할 스크립트를 추가하고 저장한다.
import pymysql
import osfrom config import args
args['JOB_NAME'] = os.path.basename(__file__)aurora_conn=pymysql.connect(
host='****.****.****',
port=****,
user='********',
password='********',
database='mysql',
cursorclass=pymysql.cursors.DictCursor
)auroar_cursor = aurora_conn.cursor()
auroar_cursor.execute('show create table user')
res = auroar_cursor.fetchall()
aurora_conn.close()print(res)
스크립트 저장 후 목록에서 해당 Job을 수동으로 실행할 수 있다. 처음 실행이라면 간단한 스크립트라도 구동 시까지 최대 1분 정도 시간이 소요될 수도 있다. Run status
에서 Succeeded가 나타나면 성공이다. 실행 결과는 Logs
에서 확인할 수 있는데 클릭하면 CloudWatch로 이동한다.
3. Workflow 추가
CloudWatch의 Events 처럼 특정 시간에 하나의 Job을 구동하려면 Trigger를 추가하면 된다. 하지만 여러 개의 Job을 워크 플로우에 따라 순차적으로 실행하거나 병렬로 실행하고 싶다면 Workflows 메뉴에서 Trigger를 생성하는 것이 좋다. 또한, Triggers 메뉴에서 생성한 Trigger는 Workflows에서 그대로 사용할 수 없고 반드시 복제해서 사용해야 하므로 깔끔한 관리를 위해 Workflows에서 필요한 Trigger를 생성하는 것이 좋다.
AWS Glue > ETL > Workflows에서 Add workflow
버튼을 클릭해 Workflow를 추가해 준다. 우선 이름을 test-workflow
로 입력하고 Workflow를 추가해 준다.
Workflow를 추가하면 아래와 같이 Graph 탭에 Trigger를 추가할 수 있는 화면이 나온다.
‘Add trigger’ 버튼을 클릭하면 Trigger를 Clone 해서 생성하거나 신규로 생성할 수 있는 팝업이 뜬다. Add new
탭을 클릭하고 새로운 Trigger를 추가해 준다.
특정 시간에 실행하기 위해 Trigger type은 Schedule로 등록한다. 실행 주기와 실행 시간을 입력할 수 있다. 시간은 UDT 기준이다.
Trigger 등록하면 아래와 같이 특정 Job을 추가할 수 있는 에디터 화면이 나타난다. 여기에서 Add node
를 클릭해 만들어 둔 test-aurora
Job을 추가한다.
이 상태에서 trigger-test
를 선택하면 병렬로 실행할 Job을, test-aurora
Job을 선택하면 이어서 실행할 Trigger를 추가할 수 있다. 간단한 추가 작업으로 아래와 같이 병렬로 실행 후 마무리 작업하는 Workflow를 추가할 수 있다.
trigger-test-2
는 구동 조건을 선택할 수 있는데 병렬로 실행된 이전 Job들이 하나라도 실행되었거나 모두 실행되었을 경우를 선택하거나 이전 Job들이 성공했을 경우 또는 실패했을 경우를 선택할 수 있다. 이런 방식으로 Job들을 다양하게 조합할 수 있고 성공하거나 실패했을 때 유연하게 처리가 가능하다.
구동할 Workflow가 선택된 상태에서 Actions
> Run
을 클릭하면 해당 Workflow가 실행된다. 실행 상태는 목록에서 바로 확인이 가능하다. 결국 Workflow에 따라 실행되는 것은 Job이므로 자세한 실행 로그를 확인하고 싶을 때는 Jobs 목록에서 실행한 Job 로그로 확인할 수 있다.
여기까지 AWS Glue에서 간단한 배치 시스템을 어떻게 구성할 수 있는지 알아 보았다. 다음은 설정 시 겪을 수 있는 몇 가지 오류와 해결 방법에 대해서 간단하게 소개하고자 한다.
몇 가지 트러블 슈팅
Job이 실패하는 대부분의 케이스는 Job 스크립트를 잘못 작성하는 경우라 에러 로그를 통해 쉽게 원인을 찾을 수 있다. 가끔씩 자세한 오류 없이 Job이 실패하는 경우가 있는데 대부분 아래와 같이 설정에서 해결이 가능하다.
Timeout이 발생한다면?
배치 수행 시간이 길어질 경우 Jobs > Action > Edit Job > Job timeout 에서 Timeout을 수정할 수 있다. default가 2880분이므로 해당 시간이 넘어갈 경우는 극히 드물다.
메모리 부족 에러가 발생할 경우?
Job 스크립트에서 대량의 데이터를 메모리에 올려서 조작할 경우 메모리 부족 에러가 발생할 수 있다. Jobs > Action > Edit Job > Maximum capacity의 값을 0.0625가 아닌 1로 수정해서 테스트해 보자.
Internal service error라고만 표시될 경우?
메모리 부족이나 프로세싱 파워가 부족할 경우 가끔 아무런 에러 메시지 없이 Internal service error라고만 뜨는 경우가 있다. 다시 시도해도 동일 에러가 계속 발생할 경우 메모리 부족 에러와 같이 Maximum capacity를 보다 큰 값으로 주어 해결이 될 때가 있으니 참고하자.
맺음말
지금까지 AWS Glue를 이용해 배치 시스템을 만드는 방법을 살펴 보았다. AWS Glue는 서버리스 데이터 ETL 시스템이지만 배치 시스템에 필요한 대부분의 기능을 모두 가지고 있고 또 간단하게 설정이 가능하다. 구동하려는 배치가 간단한 구성만으로도 충분하다면, 그리고 배치 시스템이 다운될 걱정없이 맘 편히 지내고 싶다면 AWG Glue를 서버리스 배치 시스템으로 사용하는 것도 괜찮은 선택지 중 하나라고 생각된다.
References
- What Is AWS Batch?, https://docs.aws.amazon.com/en_us/batch/latest/userguide/what-is-batch.html
- AWS Glue Job, https://docs.aws.amazon.com/en_us/glue/latest/dg/aws-glue-api-jobs-job.html
- Using Python Libraries with AWS Glue, https://docs.aws.amazon.com/glue/latest/dg/aws-glue-programming-python-libraries.html, (Glue 2.0 기준이라 1.0과 맞지 않을 수 있다.)