The batch process by AWS SQS/Lambda

YOHAN CHAE
5 min readDec 25, 2019

--

Back-End 서버를 개발하다 보면 종종 많은 양의 데이터를 그것도 수시로 처리해야 하는 경우가 있다.

대표적인 예로

  1. DB의 Data를 불러와 원하는 방향으로 처리 후 Update 시킨다거나
  2. 외부로부터 API 호출이 들어와 상응하는 Data를 처리하거나
  3. Scheduled Job을 처리하는 등 많은 상황이 있겠다.

필자의 경우 Back-End 서버로 AWS EC2 + Sprint Boot를 활용하여 외부 API 호출을 처리하는데

API 호출에 대한 Response와 Job을 분리하고자 AWS SQS/Lambda를 사용하게 되었다.
(여기서 Job이라 함은 API 호출에 따른 Batch Job인데 API 서버에게 10,000명 이상의 User Data를 처리하게 함은 너무 Burden이라 생각하여 분리하게 되었다. 그리고 LB에 의해서 여러 EC2가 하나의 Endpoint가 묶여있는 경우, 여러 EC2가 동시에 Batch job이 실행되어 상호 Relay를 하여 중복 Data 처리 등의 이슈를 미연에 방지코자 함이다.)

참고로 AWS SQS/Lambda 조합을 사용한 주된 이유는 SQS의 Lambda trigger 기능 때문이다.

SQS에 Lambda trigger만 설정해준다면 내가 별도로 처리를 하지 않아도

Enqueue에 대해서는 자동으로 Lambda로 전달되게 된다

(https://docs.aws.amazon.com/ko_kr/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-configure-lambda-function-trigger.html)

하기의 이미지는 Cloudcraft(https://cloudcraft.co/)를 활용하여 만든 Blueprint이다

Server(AWS EC2/SQS/Lambda) Blueprint

간략한 소개를 하면

  1. 외부에서의 API Invocation
  2. EC2는 Invocation을 분석 후 SQS로 전달(필자의 경우 전체 User List를 전달했다)
  3. SQS는 Enqueue에 대해 자동으로 Lambda 함수로 전달
  4. Lambda는 SQS로 부터 전달받은 Data를 처리(필자의 경우 Data를 분석 후 Redis로 Data를 저장했다. 경우에 따라 RDS 등 수많은 방법이 있겠다.)
  5. 처리한 Queue는 자동으로 삭제

추가로 SQS에서 Lambda trigger 이외에도 장점을 손꼽는다면 trigger 시에 자동으로 Lambda intance(worker)가 여러 개가 실행된다는 점이다.

정확히 어떤 기준으로 몇 개의 intance가 실행되는지는 확인해보지 못했지만

Lambda trigger 시 Cloudwatch를 확인해보면 불과 10개의 queue에 대해서도 4~5개의 intance가 실행되어 병렬 처리됨을 확인할 수 있었다.

마지막 이벤트 시간에서 볼 수 있듯이 3~5개의 lambda worker들이 거의 동시에 병렬로 job을 수행한다

다만 위의 환경을 사용하기 위해서는 몇 가지 Pre-condition이 존재하는데

  1. 서버(e.g. Spring boot on EC2)에서 SQS를 호출 시 SDK를 통한 연결 (https://docs.aws.amazon.com/ko_kr/sdk-for-java/v1/developer-guide/examples-sqs-messages.html)
  2. SQS에 Lambda를 묶기 전, Lambda role에 SQS policy가 추가되어 있어야 함

가 대표적이겠다. (앞서 말했듯이 필자가 사용한 Redis의 경우 별도 Security group로 구분해놨기에 Lambda와 Redis 간에 상호 Security group in/out bound를 설정해두었다.)

SQS에 의해 Lambda에 전달되는 Data는 하기의 code를 통해 확인할 수가 있다. (NodeJs / https://docs.aws.amazon.com/ko_kr/lambda/latest/dg/with-sqs-create-package.html#with-sqs-example-deployment-pkg-nodejs)

exports.handler = async function(event, context) {
event.Records.forEach(record => {
const { body } = record;
console.log(body);

});
return {};
}

사실 SQS/Lambda의 조합을 고려하기 전에 Sprint boot daemon(scheduled job)도 고려했지만

  1. 별도 EC2에 대한 관리
  2. 실시간 데이터 처리(SQS로 전달하면 거의 바로 전달되지만 schedule 시에 설정에 따라 time gap이 존재할 수 있다)

의 이슈 등으로 빠른 포기를 하였다

Batch Job의 분리 및 Serverless를 고민하고 있는 분이라면 충분히 try 해볼 만하다고 생각한다.

--

--

YOHAN CHAE
YOHAN CHAE

Written by YOHAN CHAE

0 Followers

Front/Back-End developer, AWS Solutions Architect - Associate

No responses yet