home

견고한 sqs

  • 중요한 메시지를 처리하거나 중복되어 실행되면 안되는 로직이 있을 때, SQS에서 딱 한번만 메시지를 멱등성 있게 처리하기 위해서 SQS를 튜닝해보자
  • 아키텍처는 특정 메시지 발행처로부터(예시는 람다가 publish) SQS는 메시지를 받고, 수신하는 람다가 이를 처리한다.

SQS 생성시

  • 중복 제거를 MessageDeduplicationId를 통해서 자동으로 해주는 FIFO SQS를 선택
  • 하지만 중복 제거의 방법은 컨텐츠 기반 중복 제거도 존재한다.

컨텐츠 기반 중복 제거와 MessageDeduplicationId 설정 차이

  • 컨텐츠 기반 중복제거
    • 따로 ID를 설정해줄 필요 없이 자동으로 메시지 본문을 해시하여 중복을 제거
    • 커스텀하기 어렵고, 메시지가 큰 경우 효율이 안 좋음
  • MessageDeduplicationId 기반 중복 제거
    • 본문 이외의 다른 요소로 중복 제거 (예: 메시지 별 UUID 생성, timestamp 등)
    • 직접 생성해야하지만 커스텀 하거나 비지니스 로직에 맞춘 중복 제거가 가능
  • 메시지 별로 UUID를 생성해서 중복을 제거하는 것이 자동으로 중복 제거되는 것 보다 명시적이고 확실할 것 같아서 후자를 택

MessageGroupId

  • FIFO SQS의 메시지 순서 보장에 중요한 역할
  • 같은 MessageGroupId를 가진 메시지는 해당 그룹 내에서 순서대로 처리
  • 서로 다른 MessageGroupId 를 가진 메시지는 병렬로 처리
  • 설정 기준
    • 메시지 그룹을 어떻게 식별할 것인가의 비지니스 적인 결정
    • 예를 들어 특정 사용자의 주문 메시지는 동일한 MessageGroupID로 묶을 수 있음
    • 다른 사용자들의 주문 메시지는 다른 그룹이기 때문에 병렬 처리가 가능
    • user_id나 category_id로 나눌 수 있다.
    • 그룹ID가 너무 많으면 다른 메시지와의 순서를 보장하기 어렵고, 너무 적으면 병렬 처리가 불가능해 성능이 좋지 않다.
    • 모니터링을 통해서 최적화 필요

Lambda Trigger 생성시

  • 람다 트리거로 SQS를 설정할 때 고려해야할 설정이 존재한다.

SQS 트리거 동작 방식

  • 기본 동작 방식은 Lambda가 큐를 폴링하고 이벤트와 함께 동기적으로 함수를 호출
  • Lambda는 이러한 이벤트를 한 번에 하나의 배치씩 수신하고, 각 배치에 대해 한 번씩 함수를 호출
  • Lambda 함수가 성공적으로 배치를 처리하면 해당 메시지는 SQS 큐에서 자동 삭제
  • Lambda 함수 실행 중 에러가 발생하면, 메시지는 삭제되지 않고 재시도 정책에 따라 다시 처리
  • 문제는 배치의 visibility timeout이 만료된 이후 큐에 다시 보낸다.
  • 그래서 중복 실행 방지를 위해서 멱등성 있게 구성해야함

배치크기

  • Lambda가 SQS에서 한 번에 가져올 메시지의 최대 개수를 의미
  • 배치 크기가 클수록 한 번의 Lambda 호출로 더 많은 메시지를 처리할 수 있어 효율성이 높아짐
  • 배치 크기가 너무 크면, 한 번에 많은 메시지를 처리해야 하므로 Lambda 실행 시간이 길어짐, 또한 충분한 메시지가 모일 때 까지 기다려야 함
  • 배치 크기가 작을 수록 메시지를 더 빨리 처리할 수 있지만 람다의 호출 빈도가 높아진다.
  • 작은 배치 크기는 오류 발생 시 재처리할 메시지의 수를 줄여준다.
  • 멱등성을 위해서는 배치 크기를 작게 하는 것이 좋지만, 호출 빈도를 증가시킬 수 있다.
  • FIFO SQS의 경우 배치 크기는 기본이 10이다.