Overview

풀필먼트개발팀은 Serverless 환경에서 운영 가능한 다양한 AWS 서비스를 사용하고 있습니다. 대용량 데이터를 추출하여 엑셀 파일로 저장하는 배치성 작업을 구현하기 위해 AWS Lambda 로 소스 코드를 작성하였으나, 실행 과정에서 Lambda 의 제한된 스토리지 용량으로 대안이 필요하였습니다. 이에 따라 AWS Batch 로 변경하고 Step Functions 를 활용하여 하나의 워크플로우로 엮은 경험을 토대로 배치 및 Step Functions에 대해 소개하고자 합니다.

Contents

  1. 배치 작업을 위한 Lambda vs Batch
  2. Step Functions 란?
  3. Step Functions 사용하기
  4. Conclusion


배치 작업을 위한 Lambda vs Batch


AWS Lambda

브랜디 랩스 민세님의 글에 잘 설명된 바와 같이 Lambda 의 메모리 할당은 128MB 부터 10,240MB 까지 설정할 수 있지만, 900초의 제한 시간이 있고 스토리지 용량이 512MB로 고정되어 있습니다.

제가 구현할 기능은 15분 이내에 작동되는 단순한 작업이므로, Lambda 로 엑셀 파일을 생성하여 s3에 업로드하는 소스 코드를 작성하고 실행해 보았습니다. Lambda 생성 및 엑셀 파일을 S3에 업로드 하는 방법 역시 기존 브랜디 랩스 포스팅에서 확인하실 수 있습니다.

그러나 이번 작업의 경우, 데이터가 너무 많아 엑셀 작성 과정에서 스토리지 용량인 512MB 를 넘게 되었습니다.

athena
AWS Lambda 로 대용량 엑셀파일 생성하기 - 절망편


AWS Batch

AWS Batch 는 석호님의 글에서 잘 설명되었듯이 “배치 컴퓨팅 작업을 효율적으로 실행할 수 있게 도와줍니다. 배치 작업량과 리소스 요청을 기반으로 최적의 리소스 수량 및 인스턴스 유형을 동적으로 프로비져닝”하기 때문에 스토리지 문제를 해결 할 수 있습니다. 결국 Lambda 대신 AWS Batch 를 사용하기로 계획을 변경하였습니다.

이 배치작업은 전술했듯 많은 데이터를 조회하는 작업이므로 clone DB 를 사용하기로 하였고, 따라서 데이터를 조회하는 batch 작업에 직접 트리거를 거는 대신 데이터 조회 전후로 clone DB 를 생성하고 삭제하는 작업을 포함하게 되었습니다.

  1. Lambda : Clone DB 생성
  2. Batch : 데이터 조회 및 엑셀 파일 s3 업로드
  3. Lambda : Clone DB 삭제

이처럼 Lambda 와 Batch 서비스를 단계적으로 실행할 목적으로 Step Functions 를 사용하여 하나의 워크플로우로 구성하기로 하였습니다.


Step Functions 란?


AWS 는 다양한 서비스를 하나의 워크플로우로 엮어주는 클라우드 오케스트레이션 서비스인 Step Functions 를 지원합니다. Step Functions 는 유연한 병렬/분기의 흐름을 손쉽게 제어할 수 있고, 워크플로우를 시각적으로 확인할 수 있습니다.

💡
시각화한 Step Functions 워크플로우 예시


Step Functions 의 특징을 간단하게 정리하자면 다음과 같습니다.

  • 워크플로우 형태로 가시화하는 에디터 기능 제공
  • AWS 서비스들을 조직화하여 단계별로 실행
  • 각 단계를 자동으로 트리거하고 추적
  • State (상태)를 사용한 분산 트랜잭션


Step Functions 사용하기


아래의 순서로 AWS Step Functions 의 사용 방법을 알아보겠습니다.

  1. 작성 방법 선택
  2. 유형 선택
  3. 상태 시스템 설정 지정
  4. 실행 결과 확인


1. 작성 방법 선택

athena

시각적으로 워크플로 설계 를 선택해보겠습니다.

athena

좌측 작업 탭에서 컴퓨팅, 스토리지, 데이터베이스, 마이그레이션 및 전송, 네트워킹 및 콘텐츠 전송, 컨테이너 등등 다양한 AWS 서비스를 선택할 수 있고, 흐름 탭에서 Wait, Choice, Parallel, Pass, Map 등 플로우의 유형을 선택할 수 있습니다. 선택한 작업 및 흐름을 오른쪽으로 드래그하여 간단하게 워크플로우를 구성할 수 있습니다.

제가 구현하는 작업인 Clone DB 를 생성하고, 배치작업 실행 후 DB 를 삭제하는 워크플로우를 간략하게 만들어보았습니다. Clone DB 생성 후 잠시 기다려주는 wait 타입의 작업도 드래그하여 추가해주었습니다.

각 작업을 클릭하여 미리 생성해둔 Lambda 나 Batch 작업을 우측에서 지정해줍니다.

athena

다음 단계로 넘어가면 위의 비주얼 워크플로우가 Step Functions 을 정의하는 언어인 JSON 기반의 Amazon State Language 로 변환, 코드화된 것을 확인하실 수 있습니다.

{
  "Comment": "A description of my state machine",
  "StartAt": "Create Clone DB",
  "States": {
    "Create Clone DB": {
      "Type": "Task",
      "Resource": "arn:aws:states:::lambda:invoke",
      "OutputPath": "$.Payload",
      "Parameters": {
        "Payload.$": "$",
        "FunctionName": "My-Lambda-Create-Clone-DB-Lambda"
      },
      "Retry": [
        {
          "ErrorEquals": [
            "Lambda.ServiceException",
            "Lambda.AWSLambdaException",
            "Lambda.SdkClientException"
          ],
          "IntervalSeconds": 2,
          "MaxAttempts": 6,
          "BackoffRate": 2
        }
      ],
      "Next": "Wait"
    },
    "Wait": {
      "Type": "Wait",
      "Seconds": 300,
      "Next": "Batch Job"
    },
    "Batch Job": {
      "Type": "Task",
      "Resource": "arn:aws:states:::batch:submitJob.sync",
      "Parameters": {
        "JobDefinition": "job-definition",
        "JobName": "My_Batch_Job_Name",
        "JobQueue": "JobQueue"
      },
      "Next": "Delete Clone DB"
    },
    "Delete Clone DB": {
      "Type": "Task",
      "Resource": "arn:aws:states:::lambda:invoke",
      "OutputPath": "$.Payload",
      "Parameters": {
        "Payload.$": "$",
        "FunctionName": "My-Lambda-Delete-Clone-DB-Lambda"
      },
      "Retry": [
        {
          "ErrorEquals": [
            "Lambda.ServiceException",
            "Lambda.AWSLambdaException",
            "Lambda.SdkClientException"
          ],
          "IntervalSeconds": 2,
          "MaxAttempts": 6,
          "BackoffRate": 2
        }
      ],
      "End": true
    }
  }
}

위의 코드에서 Step Functions 를 구성하는 가장 핵심적인 필드를 설명하겠습니다.

  • StartAt : 상태머신이 실행되면 StartAt 필드에 참조된 상태로 시작합니다. 하나의 상태만 start 상태로 지정되어 있을 수 있습니다.
  • States : 상태는 상태 머신의 요소로, 개별 상태는 인풋을 토대로 결정하고, 작업을 수행하며, 출력을 다른 상태로 전달할 수 있습니다. 상태는 전체 상태 머신 범위 내에서 고유해야 하고 중복될 수 없는 name으로 참조됩니다. 아래는 각 상태를 구성하는 필드의 일부입니다.
    • Type : 상태 유형을 나타내는 필수 필드입니다.
      • Task, Choice, Fail or Successed, Pass, Wait 등 다양한 유형이 있습니다.
    • Next : 성공 여부에 따라 상태머신 실행을 중지시키는 Fail or Successed 타입을 제외한 모든 상태는 필수적으로 Next 필드로 다음 상태를 참조하거나 End 필드를 가져야 합니다.
    • End : true 의 값을 가지며, 해당 상태는 전체 상태 머신의 실행을 종료시키는 상태가 됩니다. 여러 개의 상태에 해당 필드를 추가할 수 있습니다. Choice 와 같은 일부 타입에서는 End 필드를 사용할 수 없습니다.

직접 설정한 내용 외에 자동으로 생성된 부분은 Retry 부분입니다. Retry 는 타입이 Task 혹은 Parallel 인 상태의 재시도에 관한 설정입니다. 간단히 소개해드리자면,

  • ErrorEquals (필수) : 캐치할 에러명의 배열. 에러가 발생하면 Step Functions 이 캐치하여 재시도
  • IntervalSeconds (옵션) : 재시도 간격 (초). 기본값은 1, 최대 99999999
  • MaxAttemps (옵션) : 최대 재시도 횟수. 기본값은 3, 최대 99999999
  • BackoffRate (옵션) : 재시도 간격의 증가 비율. 기본값은 2.0

작성 방법 중 코드로 워크플로 작성 을 선택하게 되면, 시각적 워크플로 설계와 반대로 Amazon State Language 를 직접 작성하여 워크플로를 구성하고, 이를 토대로 생성된 비주얼 워크플로우를 확인할 수 있습니다.


2. 유형 선택

작성 방법을 선택하고 그 아래에서 유형을 선택합니다. 작동 유형은 표준Express 가 있습니다.

athena

표준 유형은 장기 실행되고 지속적이며 모니터링이 가능한 워크플로에 적합합니다. Express 유형은 IoT 데이터 수집, 스트리밍 데이터 처리 및 변환, 모바일 애플리케이션 백엔드 등의 대용량 이벤트 처리 워크로드에 적합합니다.

<표 : Step Functions 유형에 따른 특징 비교>

  표준 Express
최대 지속 기간 1년 5분
실행 시작 비율 초당 2,000회 이상 초당 100,000회 이상
상태 전환 비율 계정당 초당 4,000회 이상 거의 무제한
요금 상태 전환당 (서울 리전은 상태 전환 1,000번 당 0.0271 USD) 실행 횟수 (요청 1백만 건당 1.00 USD), 실행 기간, 메모리 소비량에 따라
실행 내역 Step Functions API 에 나열, 설명되고 콘솔을 통해 시각적으로 디버그깅 할 수 있음 상태 머신 로깅을 활성화하여 CloudWatch Logs 에서 확인 가능
실행 시맨틱 1회만 실행 - 비동기식 : 최소 1회 실행 - 동기식 : 1회만 실행
서비스 통합 모든 서비스 통합 및 패턴 지원 모든 서비스 통합을 지원. 작업 실행(.sync) 또는 콜백(.waitForTaskToken) 패턴을 미지원
Step Functions 활동 지원 미지원

제가 이번에 구현한 작업의 실행 시간은 10분 정도이므로 표준 유형을 선택하였습니다.

이처럼 리전별 비용, 실행 횟수, 실행 기간, 메모리 소비, 상태 전환 횟수 등을 고려하여 적절한 유형을 선택합니다.


3. 상태 시스템 설정 지정

상태 머신 이름, 권한, 로깅, 추적 및 태그(옵션)를 지정하는 페이지입니다. 저는 새 역할과 새 로그 그룹을 생성하였습니다.

athena


4. 실행 결과 확인

새로 생성한 상태 머신의 상세 페이지에서 실행 시작 버튼을 눌러 수동으로 Step Functions 를 실행합니다.

Graph inspector 에는 단계별 실행 여부 및 결과가 시각적으로 표현됩니다. batch job 수행을 실패하여 빨간색으로 표시되었고, 다음 상태가 실행되지 않았습니다.

Graph inspector 아래 실행 이벤트 내역에서는 로깅을 확인 할 수 있습니다.

athena
(에러는 일부러 낸 것입니다!)


상태 시스템 설정 지정 에서 새로 생성했던 로그 그룹에서도 전체 로그를 확인할 수 있습니다.

athena

각 실행 내역도 로깅 되어 있습니다.

athena

잘못된 코드를 수정하여 정상 작동 확인 후, 주기적으로 Step Functions 을 실행하기 위해 Amazon EventBridge 로 트리거를 걸어주어 원하는 배치 작업을 실행할 수 있게 되었습니다.


Conclusion


이렇게 민세님과 석호님의 글을 토대로 Lambda, Batch 를 생성하여 Step Functions 으로 workflow 를 구성해 보았습니다.

간단해 보이는 작업이지만 주니어 개발자로서 AWS 의 다양한 기능에 익숙하지 않아 많은 어려움이 있었습니다. 배치작업의 관점에서 Step Function 을 추가하여 소개하다 보니 깊이 있는 글은 아니어도 큰 틀에서 접근하기에 작은 도움이 되는 글이었으면 좋겠습니다.

긴 글 읽어주셔서 감사합니다.


참고 페이지


Amazon State Language : https://docs.aws.amazon.com/ko_kr/step-functions/latest/dg/concepts-states.html

표준, Express 유형 비교 : https://docs.aws.amazon.com/ko_kr/step-functions/latest/dg/concepts-standard-vs-express.html

Step Functions 오류 처리 : https://docs.aws.amazon.com/ko_kr/step-functions/latest/dg/concepts-error-handling.html


김수정 | 풀필먼트개발실 풀필먼트개발팀
브랜디, 오직 예쁜 옷만