Lambda를 Amazon SQS와 함께 사용

Lambda를 Amazon SQS와 함께 사용

참고
Lambda 함수가 아닌 다른 대상으로 데이터를 보내거나 데이터를 보내기 전에 보강하고 싶다면 Amazon EventBridge Pipes를 참고하세요.

Lambda 함수를 사용해 Amazon Simple Queue Service(Amazon SQS) 큐의 메시지를 처리할 수 있어요. Lambda는 이벤트 소스 매핑에 표준 큐와 FIFO(선입선출) 큐를 모두 지원해요. 또한 프로비저닝 모드를 사용해 Amazon SQS 이벤트 소스 매핑에 전용 폴링 리소스를 할당할 수 있죠. Lambda 함수와 Amazon SQS 큐는 같은 AWS 리전에 있어야 하지만, 다른 AWS 계정에 있을 수는 있어요.

Amazon SQS 메시지를 처리하는 예제 함수는 튜토리얼: Lambda를 Amazon SQS와 함께 사용을 참고하세요. 교차 계정 처리는 튜토리얼: 이벤트 소스로 교차 계정 Amazon SQS 큐 사용을 참고하세요. 전체 구성 옵션 목록은 Amazon SQS 이벤트 소스 매핑용 Lambda 매개변수를 참고하세요.

Amazon SQS 메시지를 처리할 때는 배치 내 일부 메시지가 실패할 때 이미 성공적으로 처리된 메시지가 재시도되지 않도록 부분 배치 응답(partial batch response) 로직을 구현해야 해요. Powertools for AWS Lambda의 배치 프로세서(Batch Processor) 유틸리티는 부분 배치 응답 로직을 자동으로 처리해 구현을 간소화하고 개발 시간을 줄이며 안정성을 높여줘요.

출처: AWS Lambda 개발자 안내서

본문

Topics(주제)

Amazon SQS 이벤트 소스 매핑의 폴링·배칭 동작 이해

Amazon SQS 이벤트 소스 매핑에서 Lambda는 큐를 폴링하고 이벤트로 함수를 동기식으로 호출해요. 각 이벤트는 큐의 여러 메시지 배치를 담을 수 있어요. Lambda는 이러한 이벤트를 한 번에 한 배치씩 받고, 각 배치에 대해 함수를 한 번 호출하죠. 함수가 배치를 성공적으로 처리하면 Lambda는 그 메시지들을 큐에서 삭제해요.

Lambda가 배치를 받으면 메시지는 큐에 남아 있지만 큐의 표시 제한 시간(visibility timeout) 길이만큼 숨겨져요. 함수가 배치의 모든 메시지를 성공적으로 처리하면 Lambda는 메시지를 큐에서 삭제해요. 기본적으로 함수가 배치 처리 중 오류를 만나면 표시 제한 시간이 만료된 후 그 배치의 모든 메시지가 큐에서 다시 보이게 되죠. 따라서 함수 코드는 의도하지 않은 부작용 없이 같은 메시지를 여러 번 처리할 수 있어야 해요.

경고
Lambda 이벤트 소스 매핑은 각 이벤트를 최소 한 번은 처리하며, 레코드의 중복 처리가 발생할 수 있어요. 중복 이벤트와 관련된 잠재적 문제를 피하려면 함수 코드를 멱등(idempotent)하게 만드는 것을 강력히 권장해요. 자세한 내용은 AWS Knowledge Center의 Lambda 함수를 멱등하게 만드는 방법을 참고하세요.

Lambda가 메시지를 여러 번 처리하지 못하게 하려면 함수 응답에 배치 항목 실패를 포함하도록 이벤트 소스 매핑을 구성하거나, Lambda 함수가 메시지를 성공적으로 처리할 때 DeleteMessage API를 사용해 큐에서 메시지를 제거할 수 있어요.

SQS 이벤트 소스 매핑에 대해 Lambda가 지원하는 구성 매개변수에 대한 자세한 내용은 SQS 이벤트 소스 매핑 생성을 참고하세요.

Amazon SQS 이벤트 소스 매핑에서 프로비저닝 모드 사용

이벤트 소스 매핑의 처리량을 미세 조정해야 하는 워크로드에는 프로비저닝 모드를 사용할 수 있어요. 프로비저닝 모드에서는 프로비저닝된 이벤트 폴러(event poller)의 양에 대한 최소·최대 한도를 정의해요. 이러한 프로비저닝된 이벤트 폴러는 이벤트 소스 매핑 전용이며, 반응형 자동 스케일링으로 예상치 못한 메시지 급증을 처리할 수 있죠. 프로비저닝 모드로 구성된 Amazon SQS 이벤트 소스 매핑은 기본 Amazon SQS 이벤트 소스 매핑 기능보다 3배 빠르게 스케일링(분당 최대 1,000개 동시 호출)되고 80배 높은 동시성(최대 100,000개 동시 호출)을 지원해요.

엄격한 성능 요구 사항이 있는 Amazon SQS 이벤트 기반 워크로드에는 프로비저닝 모드를 사용하는 것이 좋아요. 예를 들어 시장 데이터 피드를 처리하는 금융 서비스 기업, 실시간 개인화 추천을 제공하는 전자상거래 플랫폼, 실시간 플레이어 상호작용을 관리하는 게임 회사 등이죠. 프로비저닝 모드를 사용하면 추가 비용이 발생해요. 자세한 요금은 AWS Lambda 요금을 참고하세요.

프로비저닝 모드의 각 이벤트 폴러는 최대 1MB/s의 처리량, 최대 10개의 동시 호출, 또는 초당 최대 10개의 Amazon SQS 폴링 API 호출을 처리할 수 있어요. 이벤트 폴러 최소 수(MinimumPollers)의 허용 값 범위는 2에서 200이며 기본값은 2예요. 이벤트 폴러 최대 수(MaximumPollers)의 허용 값 범위는 2에서 10,000이며 기본값은 200이에요. MaximumPollers는 MinimumPollers보다 크거나 같아야 합니다.

필요한 이벤트 폴러 결정

SQS ESM에 프로비저닝 모드를 사용할 때 최적의 메시지 처리 성능을 보장하는 데 필요한 이벤트 폴러 수를 추정하려면 애플리케이션에 대해 다음 지표를 수집하세요: 저지연 처리가 필요한 초당 최대 SQS 이벤트 수, 평균 SQS 이벤트 페이로드 크기, 평균 Lambda 함수 실행 시간, 구성된 배치 크기.

먼저 다음 공식으로 워크로드에 대해 이벤트 폴러 하나가 지원하는 초당 SQS 이벤트 수(EPS)를 추정할 수 있어요:

EPS per event poller = 
        minimum(
            ceiling(1024 / average event size in KB),
            ceiling(10 / average function duration in seconds) * batch size, 
            min(100, 10 * batch size)
                )

그런 다음 아래 공식으로 필요한 최소 폴러 수를 계산할 수 있어요. 이 계산은 최대 트래픽 요구 사항을 처리할 충분한 용량을 프로비저닝하도록 보장해요.

Required event pollers = (Peak number of events per second in Queue) / EPS per event poller

기본 배치 크기 10, 평균 이벤트 크기 3KB, 평균 함수 실행 시간 100ms, 초당 1,000개 이벤트 처리가 필요한 워크로드를 생각해 보세요. 이 시나리오에서 각 이벤트 폴러는 약 초당 100개 이벤트(EPS)를 지원해요. 따라서 최대 트래픽 요구 사항을 적절히 처리하려면 최소 폴러를 10으로 설정하는 것을 권장해요. 워크로드 특성이 같지만 평균 함수 실행 시간이 1초라면 각 폴러는 10 EPS만 지원하므로, 초당 1,000개 이벤트를 저지연으로 지원하려면 최소 폴러 100개를 구성해야 해요.

프로비저닝 모드 이벤트 폴러의 효율을 최대화하려면 기본 배치 크기 10 이상을 사용하는 것을 권장해요. 배치 크기가 클수록 각 폴러가 호출당 더 많은 이벤트를 처리해 처리량과 비용 효율이 좋아지죠. 이벤트 폴러 용량을 계획할 때는 잠재적 트래픽 급증을 고려하고 계산된 최솟값보다 약간 높게 minimumPollers 값을 설정해 버퍼를 확보하세요. 또한 시간이 지남에 따라 메시지 크기, 함수 실행 시간, 트래픽 패턴이 변하면 이벤트 폴러 구성을 조정해야 최적의 성능과 비용 효율이 유지될 수 있으므로 워크로드 특성을 지속적으로 모니터링하세요. 정확한 용량 계획을 위해 특정 워크로드를 테스트해 각 이벤트 폴러가 실제로 구동할 수 있는 실제 EPS를 확인하는 것을 권장해요.

Amazon SQS 이벤트 소스 매핑용 프로비저닝 모드 구성

콘솔 또는 Lambda API로 Amazon SQS 이벤트 소스 매핑의 프로비저닝 모드를 구성할 수 있어요.

기존 Amazon SQS 이벤트 소스 매핑의 프로비저닝 모드 구성 (콘솔)

  1. Lambda 콘솔의 함수 페이지를 엽니다.
  2. 프로비저닝 모드를 구성할 Amazon SQS 이벤트 소스 매핑이 있는 함수를 선택합니다.
  3. Configuration(구성)을 선택한 다음 Triggers(트리거)를 선택합니다.
  4. 프로비저닝 모드를 구성할 Amazon SQS 이벤트 소스 매핑을 선택한 다음 Edit(편집)을 선택합니다.
  5. Event source mapping configuration(이벤트 소스 매핑 구성) 아래에서 Configure provisioned mode(프로비저닝 모드 구성)을 선택합니다.
    • Minimum event pollers에 2에서 200 사이의 값을 입력합니다. 값을 지정하지 않으면 Lambda가 기본값 2를 선택해요.
    • Maximum event pollers에 2에서 10,000 사이의 값을 입력합니다. 이 값은 Minimum event pollers 값보다 크거나 같아야 해요. 값을 지정하지 않으면 Lambda가 기본값 200을 선택합니다.
  6. Save(저장)를 선택합니다.

EventSourceMappingConfiguration의 ProvisionedPollerConfig 객체로 프로그래밍 방식으로 프로비저닝 모드를 구성할 수 있어요. 예를 들어 다음 UpdateEventSourceMapping CLI 명령은 MinimumPollers 값 5와 MaximumPollers 값 100을 구성해요.

aws lambda update-event-source-mapping \
    --uuid a1b2c3d4-5678-90ab-cdef-EXAMPLE11111 \
    --provisioned-poller-config '{"MinimumPollers": 5, "MaximumPollers": 100}'

프로비저닝 모드를 구성한 뒤에는 ProvisionedPollers 지표를 모니터링해 워크로드의 이벤트 폴러 사용률을 관찰할 수 있어요. 자세한 내용은 이벤트 소스 매핑 지표를 참고하세요.

프로비저닝 모드를 비활성화하고 기본(온디맨드) 모드로 돌아가려면 다음 UpdateEventSourceMapping CLI 명령을 사용할 수 있어요:

aws lambda update-event-source-mapping \
    --uuid a1b2c3d4-5678-90ab-cdef-EXAMPLE11111 \
    --provisioned-poller-config '{}'

참고
프로비저닝 모드는 최대 동시성(maximum concurrency) 설정과 함께 사용할 수 없어요. 프로비저닝 모드를 사용할 때는 최대 이벤트 폴러 수로 최대 동시성을 제어해요.

프로비저닝 모드 구성에 대한 자세한 내용은 Amazon SQS 이벤트 소스 매핑 생성 및 구성을 참고하세요.

예제 표준 큐 메시지 이벤트

예제 Amazon SQS 메시지 이벤트 (표준 큐)

{
    "Records": [
        {
            "messageId": "059f36b4-87a3-44ab-83d2-661975830a7d",
            "receiptHandle": "AQEBwJnKyrHigUMZj6rYigCgxlaS3SLy0a...",
            "body": "Test message.",
            "attributes": {
                "ApproximateReceiveCount": "1",
                "SentTimestamp": "1545082649183",
                "SenderId": "AIDAIENQZJOLO23YVJ4VO",
                "ApproximateFirstReceiveTimestamp": "1545082649185"
            },
            "messageAttributes": {
                "myAttribute": {
                    "stringValue": "myValue", 
                    "stringListValues": [], 
                    "binaryListValues": [], 
                    "dataType": "String"
                }
            },
            "md5OfBody": "e4e68fb7bd0e697a0ae8f1bb342846b3",
            "eventSource": "aws:sqs",
            "eventSourceARN": "arn:aws:sqs:us-east-2:123456789012:my-queue",
            "awsRegion": "us-east-2"
        },
        {
            "messageId": "2e1424d4-f796-459a-8184-9c92662be6da",
            "receiptHandle": "AQEBzWwaftRI0KuVm4tP+/7q1rGgNqicHq...",
            "body": "Test message.",
            "attributes": {
                "ApproximateReceiveCount": "1",
                "SentTimestamp": "1545082650636",
                "SenderId": "AIDAIENQZJOLO23YVJ4VO",
                "ApproximateFirstReceiveTimestamp": "1545082650649"
            },
            "messageAttributes": {},
            "md5OfBody": "e4e68fb7bd0e697a0ae8f1bb342846b3",
            "eventSource": "aws:sqs",
            "eventSourceARN": "arn:aws:sqs:us-east-2:123456789012:my-queue",
            "awsRegion": "us-east-2"
        }
    ]
}

기본적으로 Lambda는 큐에서 최대 10개의 메시지를 한 번에 폴링하고 그 배치를 함수로 보내요. 적은 수의 레코드로 함수를 호출하지 않으려면 배치 창을 구성해 이벤트 소스가 레코드를 최대 5분까지 버퍼링하게 할 수 있어요. 함수를 호출하기 전에 Lambda는 배치 창이 만료되거나, 호출 페이로드 크기 할당량에 도달하거나, 구성된 최대 배치 크기에 도달할 때까지 표준 큐에서 메시지를 계속 폴링해요.

배치 창을 사용하고 SQS 큐의 트래픽이 매우 적으면 Lambda는 함수를 호출하기 전에 최대 20초까지 기다릴 수 있어요. 배치 창을 20초 미만으로 설정해도 마찬가지예요.

참고
Java에서는 JSON을 역직렬화할 때 null 포인터 오류가 발생할 수 있어요. 이는 JSON 객체 매퍼가 "Records"와 "eventSourceARN"의 대소문자를 변환하는 방식 때문일 수 있어요.

예제 FIFO 큐 메시지 이벤트

FIFO 큐의 경우 레코드에는 중복 제거(deduplication)와 시퀀싱(sequencing) 관련 추가 속성이 포함돼요.

예제 Amazon SQS 메시지 이벤트 (FIFO 큐)

{
    "Records": [
        {
            "messageId": "11d6ee51-4cc7-4302-9e22-7cd8afdaadf5",
            "receiptHandle": "AQEBBX8nesZEXmkhsmZeyIE8iQAMig7qw...",
            "body": "Test message.",
            "attributes": {
                "ApproximateReceiveCount": "1",
                "SentTimestamp": "1573251510774",
                "SequenceNumber": "18849496460467696128",
                "MessageGroupId": "1",
                "SenderId": "AIDAIO23YVJENQZJOL4VO",
                "MessageDeduplicationId": "1",
                "ApproximateFirstReceiveTimestamp": "1573251510774"
            },
            "messageAttributes": {},
            "md5OfBody": "e4e68fb7bd0e697a0ae8f1bb342846b3",
            "eventSource": "aws:sqs",
            "eventSourceARN": "arn:aws:sqs:us-east-2:123456789012:fifo.fifo",
            "awsRegion": "us-east-2"
        }
    ]
}

더 알아보기 (Learn more)

  • SQS 폴링·배칭 동작, 프로비저닝 모드와 폴러 산정, 표준·FIFO 큐 메시지 이벤트 형식, 오류·필터링 주제를 이어서 살펴보세요.