AWS Batch 서비스는 말 그대로 Batch 프로세스 관련 서비스다.
S3의 오브젝트 파일 프로세싱이나 로그 전처리 등 배치성 일을 처리할 때, AWS Batch를 사용할 수 있다.
Tutorial은 S3 Bucket에 업로드 되는 오브젝트의 네임을 인덱싱하여, DynamoDB에 적재하는 예제를 진행한다.
AWS Batch는 EC2로 서비스 되나요? 아니면 Lambda와 같은 서버리스?
AWS Batch는 Amazon ECS와 연동된다. Batch에 수행되는 VM은 컨테이너 기반으로 동작하기 때문에 도커 이미지를 미리 생성해놔야 한다.
Batch는 AMI를 사용하나요? 레파지토리는 어떻게 구성하죠?
Batch는 사용자가 만든 AMI를 이용할 수도 있고, Amazon의 AMI를 사용할 수도 있다.
또한 도커 컨테이너 레파지토리는 Amazon ECR 혹은 Docker hub를 이용할 수 있다.
AWS Batch 구성은?
AWS Batch 구성은 위 사진으로 설명을 끝낼 수 있다.
바로 실제 예제를 구성해보며 설명을 이어가겠다.
구성은 Compute Resources(Compute environments) -> Batch Queue(Job queues) -> Job definitions 순으로 진행한다.
컴퓨팅 환경 설정하고, 그 환경을 배치 큐와 매핑한다. 그리고 Job에 대한 구성을 하고 3가지를 묶어서 Job을 생성한다.
1. 컴퓨트 리소스(Compute Resources) - Compute environments
컴퓨트 리소스는 Batch에 사용할 컴퓨팅 자원(CPU, Mem, Network 등) 설정에 대한 그룹이다.
Compute environment type: Managed(AWS 프로비저닝 및 관리), Unmanaged(고객이 직접 관리)
Unmanaged의 경우 어떤 식으로 동작하는 지 모르겠다.
Compute environment name: 그냥 batch env 이름
Service role: AWS Batch가 사용하는 Role로 EC2, ECS, CloudWatch 등 Policy 라든지.. Batch 서비스가 필요한 Role이다. (알아서 생성됨)
Instance role: ECS, ECR, CloudWatch logs 등 관련 Policy가 필요하다. (알아서 생성됨)
!실제 배치 잡에 필요한 S3, DynamoDB 등 Policy는 3번 째 단계인 Job Definitions의 Job Role에 등록한다.
아래 그림 참고
EC2 key pair: 말 그대로 인스턴스에 접근할 키 페어
Provisioning model: On-Demand 혹은 Spot을 사용할 수 있음.
Allowed instance types: optimal이 기본으로 구성하면, Job을 요청할 때 설정한 vCPU, Memory에 맞춰 적당한 인스턴스가 생성됨.
Allocation strategy: 인스턴스 할당 전략
BEST_FIT: 기본 설정으로, 이전에 설정한 EC2 type이나 vCPU에 맞게 인스턴스를 할당함. 그러나 만약 AWS에서 해당 인스턴스가 부족하면 추가될 때까지 기다림.
EST_FIT_PROGRESSIVE: 설정한 vCPU에 맞고 저렴한 EC2 타입을 선택, 적당한 EC2 타입이 모자르면 다른 EC2 type으로 인스턴스를 생성함. 아마 더 비싼 인스턴스를 생성할 수도 있는 듯? (뇌피셜임..도큐먼트 이해가 잘 안되네)
SPOT_CAPACITY_OPTIMIZED: 말 그대로 스팟 인스턴스 구성
참고: https://docs.aws.amazon.com/batch/latest/userguide/allocation-strategies.html
Launch template, Launch template version: 아래 참고(그냥 무시해도 됨.)
참고: https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-launch-templates.html
Minimum vCPUs, Desired vCPUs, Maximum vCPUs의 경우 Compute environments에 매핑될 인스턴스들의 합산 vCPU 구성이다. 따라서 무시해도 되는데, 비용을 생각하면 알아서 Maximum vCPUs를 제한하자.
또한 Minumum vCPU를 0보다 높은 값으로 해놓으면 배치 잡이 끝난 후에도 그 할당 vCPU만큼의 인스턴스들이 삭제되지 않으므로 웬만해선 0으로 해놓자.
Networking은 뭐 그냥 다른 AWS 리소스 구성이랑 동일한 설정이다.
그럼 이제 컴퓨팅 리소스 구성을 끝냈다. 컴퓨팅 리소스는 각 배치잡에 맞게 여러 개를 생성할 수 있다.
2. 배치 큐(Batch Queue) - Job queues
각 작업(Job)에 대한 Queue다.
Priority: 우선 순위를 설정한다. 이전에 생성한 Compute environment와 연결할 수 있다.
만약 Queue 1(Priority: 1)과 2(Priority: 2)가 같은 Compute environments와 연결되어 있는 상황에서, Compute environments의 자원이 모자르면 Queue 1부터 수행하고 그 다음 Queue 2를 수행한다.
또한 Queue에 Compute environment도 여러개 연결할 수 있는데, Spot의 경우 Order를 높게 해도 On-demand의 Compute environment가 같이 있으면 동작하지 않는다.
(테스트 결과임으로 틀릴 수도 있음...)
따라서 Spot을 통해 Batch를 구성하고 싶으면 Spot만 설정한 Compute environment를 연결하자.
3. Job definitions
Job definition name: 이름
Job attempts: Job 수행 실패 시, 재시도 횟수
Excution timeout: Job 타임아웃
Job requires multiple node configurations: 병렬 처리인데, 해당 내용은 안 해봄
Parameters: Command의 환경변수 값
Job role: 아래와 같이 실제 컨테이너에서 사용할 S3, DynamoDB API 등 Policy를 등록한다.
Container image: 레파지토리로 ECR이나 Docker hub 주소를 입력(예시는 도커허브 주소)
Command: Run Command
(Docker File에 분명 CMD를 적었는데, 수행이 안 된다... 아무튼 Batch Command에 적으니까 됨)
Privileged: 도커 컨테이너 Privileged 모드 (cf. docker run --privileged)
User: 도커 컨테이너 user (cf. docker run --user)
Enviorment: 도커 컨테이너 환경변수
4. Submit job
이제 Batch의 구성은 모두 했다. 마지막으로 Submit job을 한다.
Job Type을 Single과 Array로 처리할 수 있다.
Job depends on: 종속성을 갖는 수행으로, JobID를 입력하면 그 Job이 성공한 후에 순차적으로 현재 요청한 Job이 수행된다.
Array의 경우 "AWS_BATCH_JOB_ARRAY_INDEX"가 환경 변수로 컨테이너로 전달된다. 따라서 아래와 같이 스크립트를 구성하면 순차적으로 컨테이너 잡들을 사용할 수 있다. (SEQUENTIAL)
AWS_BATCH_JOB_ARRAY_INDEX=0
while [ $AWS_BATCH_JOB_ARRAY_INDEX -le 6 ]
do
docker run -e AWS_BATCH_JOB_ARRAY_INDEX=$AWS_BATCH_JOB_ARRAY_INDEX print-color
AWS_BATCH_JOB_ARRAY_INDEX=$((AWS_BATCH_JOB_ARRAY_INDEX + 1))
done
N-To-N job: 각 작업에 대한 종속성을 갖는 수행
참고: https://docs.aws.amazon.com/ko_kr/batch/latest/userguide/array_jobs.html
참고: https://docs.aws.amazon.com/ko_kr/batch/latest/userguide/example_array_job.html
기존 Job Definitions 설정을 가져온다. 수정해서 Job을 제출해도 상관없다.
5. Dashboard
Job을 제출하면 Dashboard에서 Job 실행 상황을 확인할 수 있다.
참고: https://docs.aws.amazon.com/ko_kr/batch/latest/userguide/job_states.html
수행 결과는 CloudWatch Logs를 통해 확인가능하다.
아래 에러의 경우 DynamoDB Policy로 에러가 난 모습이다.
ecsTask Role에 DynamoDB Policy를 추가하고 Job을 재실행 하고, DynamoDB를 확인하면 S3에 업로드 된 오브젝트 네임을 가져오고 URL을 생성해주는 것을 확인할 수 있다.
6. CloudWatch Event 연동
CloudWatch Event와 연동하면 주기적으로 CronJob을 이용하듯 시간대 별로 Batch를 수행 시킬 수 있다.
또한 CloudWatch Event Pattern 을 아래와 같이 주면 Batch가 성공적으로 수행된 후에 Target을 주어 사후 작업을 수행할 수도 있다.
아래와 같이 CloudWatch Event Pattern을 만들 수 있다. 그럼 jobQueue ARN의 status가 SUCCEEDED가 되면 Trigger가 일어나서, 해당 타겟으로 설정한 job이 시작된다.
{
"source": [
"aws.batch"
],
"detail-type": [
"Batch Job State Change"
],
"detail": {
"jobQueue": [
"arn:aws:batch:ap-northeast-2:557652101750:job-queue/test2"
],
"status": [
"SUCCEEDED"
]
}
}
밑에 링크를 참고해서 Batch의 ARN 값을 넣고, 원하는 Batch status에 따라 사후 작업을 진행할 수 있다.
정확한 예시가 없기 때문에 밑에 참고 링크를 보며 추측?하며 Target에는 SNS을 연동하고 테스트 할 것을 권장한다.
참고
https://docs.aws.amazon.com/AmazonCloudWatch/latest/events/CloudWatchEventsandEventPatterns.html
https://docs.aws.amazon.com/ko_kr/batch/latest/userguide/batch_cwe_events.html
S3에 업로드를 이벤트로 지정할 수 있고, Batch 수행이 완료된 것을 이벤트로 지정할 수도 있다. 전자의 경우 S3에 오브젝트가 업로드될 때마다 DynamoDB에 값을 저장한다. 후자의 경우 Batch 가 수행되고 나면 바로 또 Batch를 수행한다.
상황에 맞게 CloudWatch Event와 Batch를 조합해서 사용하면 된다.
또한 추가로 AWS Batch는 CloudWatch Event에 Step Function까지 활용해서 조금 더 복잡한 작업을 아래와 같이 가시성 있게 구성할 수도 있다.
개인적으로 학습하고 테스트 한 내용으로 틀린 부분이 있을 수도 있음..!
참고: https://www.youtube.com/watch?v=-ox2Tqs3m5s
만약 RUNNALBE 상태에서 Batch queues가 지속된다면, 아래 4가지를 의심해볼 수 있다.
1. Compute environments에서 구성한 EC2 Type의 수량이 충분하지 않아 대기 상태
2. Private Network 환경 문제
3. Role 문제(Service role, Instance role, Job role) - 적절한 Role이 구성 되었는지 확인 필요
4. Job queues에서 Disable한 Compute environments를 연결했을 시