이벤트 소스 매핑과 스트림 처리

AWS Lambda로 구축하는 서버리스 애플리케이션

Claudio Canales

Senior DevOps Engineer

이벤트 소스 매핑의 위치

  • 큐와 스트림은 배치 단위로 폴링됩니다.
  • 이벤트 소스 매핑은 폴링 및 배치 동작을 관리합니다.

이벤트 소스 매핑 위치

AWS Lambda로 구축하는 서버리스 애플리케이션

이벤트 소스 매핑이란?

  • 소스와 함수를 연결하는 리소스입니다.
  • Lambda가 소스에서 레코드를 폴링합니다.
  • Lambda가 핸들러를 배치 단위로 호출합니다.

이벤트 소스 매핑 흐름

AWS Lambda로 구축하는 서버리스 애플리케이션

푸시 vs 폴 (차이가 중요한 이유)

푸시 모델

  • 푸시 소스는 이벤트를 즉시 전송합니다.
  • 예: Amazon S3에 파일 업로드.

폴 모델

  • Lambda가 폴 소스를 직접 확인합니다.
  • Lambda가 배치를 구성한 후 핸들러를 호출합니다.
  • 지연 시간과 재시도 동작이 달라집니다.

푸시 모델 vs 폴 모델

AWS Lambda로 구축하는 서버리스 애플리케이션

큐 vs 스트림

큐 (Amazon SQS)

  • 받은 편지함과 같은 관리형 메시지 큐입니다.

스트림 (DynamoDB Streams)

  • DynamoDB 테이블의 변경 로그입니다.
  • 둘 다 Records 형태로 전달되지만 의미는 다릅니다.

큐 vs 스트림 비교

AWS Lambda로 구축하는 서버리스 애플리케이션

배치 이벤트 구조 (단순화)

{
  "Records": [{
    "messageId": "abc-123",
    "body": "{\"order_id\": \"A-42\"}"
  }]
}
  • 대부분의 매핑 이벤트는 Records로 시작합니다.
  • 각 레코드에는 messageIdbody 문자열이 있습니다.
  • body를 파싱하여 필요한 페이로드를 추출하세요.
AWS Lambda로 구축하는 서버리스 애플리케이션

실습: 레코드 처리하기

def lambda_handler(event, context):
    records = event.get("Records", [])
    for record in records:
        body = record.get("body", "")
        print("BODY:", body)
    return {"statusCode": 200}
  • Records를 기본 리스트로 읽어옵니다.
  • 각 레코드를 순회하며 body를 안전하게 읽습니다.
  • 필요한 내용을 로그로 남기고 반환합니다.
AWS Lambda로 구축하는 서버리스 애플리케이션

실습: JSON body 파싱하기

import json

def lambda_handler(event, context):
    record = event.get("Records", [])[0]
    payload = json.loads(record.get("body", "{}"))
    order_id = payload.get("order_id")
    print("ORDER_ID:", order_id)
    return {"statusCode": 200}
  • json을 임포트하고 안전한 기본값으로 body를 읽습니다.
  • json.loads로 파싱하여 딕셔너리를 얻습니다.
  • 필요한 필드를 추출하고, 항상 먼저 검증하세요.
AWS Lambda로 구축하는 서버리스 애플리케이션

배치 설정: 배치 크기와 배치 윈도우

  • 배치 크기: 호출당 처리할 레코드 수입니다.
  • 배치 윈도우: Lambda가 배치를 채우기까지 기다리는 시간입니다.
  • 배치가 클수록 처리량은 늘지만 실행당 작업량도 증가합니다.
  • SQS의 경우 ApproximateAgeOfOldestMessage로 백로그를 모니터링하세요.

배치 크기 트레이드오프 다이어그램

AWS Lambda로 구축하는 서버리스 애플리케이션

배치 크기 트레이드오프

  • 큰 배치는 효율적이지만 지연 시간이 늘어날 수 있습니다.
  • 작은 배치는 첫 처리까지의 시간을 줄이지만 호출 횟수가 증가합니다.
  • 워크로드에 맞게 선택하세요.

배치 크기 vs 지연 시간 차트

AWS Lambda로 구축하는 서버리스 애플리케이션

동시성으로 스케일링하기

  • 여러 배치가 동시에 처리됩니다.
  • 동시성이 높을수록 처리량이 증가합니다.
  • 단, 다운스트림 부하도 함께 증가합니다.

동시 배치 처리

AWS Lambda로 구축하는 서버리스 애플리케이션

다운스트림 시스템 보호

  • 동시성이 너무 높으면 데이터베이스나 API에 과부하가 걸릴 수 있습니다.
  • 제한을 설정하여 부하를 제어하세요.
  • 작고 안전한 작업 단위를 선호하세요.

다운스트림 부하 보호

AWS Lambda로 구축하는 서버리스 애플리케이션

부분 배치 실패

  • 배치에는 정상 레코드와 오류 레코드가 섞일 수 있습니다.
  • 부분 실패 처리를 하지 않으면 하나의 오류로 배치 전체가 재시도됩니다.
  • 부분 실패 처리를 사용하면 실패한 항목만 재시도할 수 있습니다.

부분 배치 실패 흐름

AWS Lambda로 구축하는 서버리스 애플리케이션

실습: 부분 실패 보고하기 (SQS)

def lambda_handler(event, context):
    failures = []
    for record in event.get("Records", []):
        try:
            process(record)
        except Exception:
            failures.append({"itemIdentifier": record["messageId"]})
    return {"batchItemFailures": failures}
  • 실패한 레코드의 messageIdbatchItemFailures에 수집합니다.
  • Lambda는 해당 항목만 재시도합니다.
  • 성공적으로 처리된 레코드는 다시 전송되지 않습니다.
AWS Lambda로 구축하는 서버리스 애플리케이션

핵심 정리

  • 이벤트 소스 매핑은 큐와 스트림을 폴링합니다.
  • Records를 배치로 묶어 핸들러에 전달합니다.
  • 배치 크기와 윈도우는 지연 시간과 처리량 간의 트레이드오프입니다.
  • 부분 실패 처리를 통해 성공한 항목의 재처리를 방지합니다.

매핑 요약 다이어그램

AWS Lambda로 구축하는 서버리스 애플리케이션

연습해 봅시다!

AWS Lambda로 구축하는 서버리스 애플리케이션

Preparing Video For Download...