크로키닷컴(지그재그)이 주기적 작업 실행 방식을 EC2 cron → Lambda + CloudWatch Events 를 거쳐 AWS Batch 로 옮긴 기록이다. CloudFormation 으로 환경·대기열·작업 정의를 어떻게 짰는지, 중복 실행은 어떻게 막았는지까지 구성 그대로 공개한다.
핵심 포인트- 서비스 서버가 EC2 → Lambda → ECS Fargate 로 옮겨질 때마다 반복 작업 실행 방식도 따라 바뀌어야 했다.
- Lambda + CloudWatch Events 는 실행 시간 제한이 있고 동시 실행을 막을 방법이 없었다.
- Fargate 로 옮긴 뒤 Scheduled Tasks 를 검토했으나 진도가 안 나가, 빠르게 전환할 수 있는 AWS Batch 를 택했다.
- 장점은 이미 ECR 에 올라간 Docker 이미지의 CMD 만 바꾸면 된다는 점, 작업 로그를 모아 보기 편하다는 점, 실패 알림을 받기 쉽다는 점이다.
- 단점은 ECS 와 달리 CPU 를 1 vCPU 단위로만 지정할 수 있어 실제 필요보다 리소스를 많이 쓴다는 점이다.
상세 정리- 초기: EC2 위에서 서비스가 돌 때는 작업 전용 EC2 인스턴스를 두고 리눅스 cron 으로 일정을 관리했다.
- 중간: Lambda 로 옮기며 CloudWatch Events 를 람다에 연결해 반복 작업을 실행했다.
- 도구 선택의 눈높이: 나중에 Airflow 같은 기능이 풍부한 해결책이 필요해질 수 있지만 현재 상황에는 AWS Batch 로 충분하다고 명시한다.
- 인프라는 CloudFormation 으로 구성하며 CDK 도 검토 중이다.
- 컴퓨트 환경: 주어진 VPC 의 서브넷 위에 상황에 맞는 인스턴스가 생성되도록 하고, 관리형을 선택해 자동으로 늘고 줄게 했다. 작업이 중단되는 것을 원치 않아 스팟 인스턴스는 쓰지 않았다.
- 대기열: 대부분의 작업은 default 대기열에서 돌린다. 다만 10분 이하 간격으로 실행되는 작업은 목록이 너무 길어져 별도 대기열로 분리하고 우선순위도 조금 낮췄다.
- 실패 알림: 작업 실패를 감지하면 CloudWatch Events 가 람다를 호출하고, 그 람다가 실패 메시지를 분석해 슬랙으로 보낸다. 람다 역할에는 `SendToSlack` 함수를 호출할 권한을 준다.
- 정의한 Batch 리소스는 다른 CloudFormation 스택에서 쓸 수 있도록 export 한다.
- 작업 정의 예시 ①: 20분 정도 걸리는 작업에 넉넉하게 30분 타임아웃을 두고 재시도는 하지 않으며, 매일 아침 9시(UTC 0시)에 실행되도록 CloudWatch Events 를 만든다.
- 작업 정의 예시 ②: 10분마다 실행되는 잦은 작업을 별도로 정의한다.
- 중복 실행 방지: 짧게 도는 작업이 겹치지 않도록 현재 구동 중인 작업을 검사하는 방식을 썼고, `batch:ListJobs` 권한이 필요하다. 이미 돌고 있으면 종료 코드 0 으로 끝내 실패로 잡히지 않게 한다.
- 순차 실행: 작업 정의만으로 여러 단계를 순서대로 제어하기는 어렵고, 이전 작업 마지막에서 `submitJob` 을 직접 호출하면 될 것으로 보고 있다.
- 미사용 기능: 노드를 여러 개 띄워 동시에 실행하는 기능은 아직 쓰지 않는다.
왜 읽나서버리스·컨테이너로 옮기면서 배치 잡을 어디서 돌릴지 정해야 하는 백엔드·인프라 담당자에게 AWS Batch 의 실제 구성과 한계를 같이 보여준다.