개론

차분한열정·2022년 4월 20일
0

AWS SQS

목록 보기
1/3

1. SQS 타입

(1) Standard

  • Unlimited Throughput: SendMessage, ReceiveMessage, or DeleteMessage 같은 API 호출을 초당 무제한에 가깝게 호출 가능
  • At-Least-Once Delivery: 보통은 하나의 메시지가 컨슈머로 전송되지만 간혹 같은 메시지가 두번 전송될 수도 있음(메시지 중복 컨슘이로 인한 문제를 방지하려면 항상 연산이 멱등성을 가지도록 만들어야 함)
  • Best-Effort Ordering: 큐에 들어온 순서와 다르게 전송될 수 있음(순서가 반드시 보장되어야 한다면 FIFO 큐를 쓰거나 각 메시지에 시퀀스 번호를 다는 방법을 쓰면 됨)

(2) FIFO(First-In-First-Out)

  • High Throughput: SendMessage, ReceiveMessage, or DeleteMessage 같은 API 호출을 초당 최대 300회 호출 가능하다.(하나의 message group 기준) 배치로 처리하면(SendMessageBatch, ReceiveMessage, or DeleteMessageBatch) 한번에 최대 10개씩 묶어서 초당 3000개의 메시지 처리 가능
  • Exactly-Once Processing: 메시지는 정확히 딱 한번만 전송됨
  • First-In-First-Out Delivery: 큐에 들어온 순서대로 전송됨
  • FIFO에서는 message group을 지원하는데 이 순서는 message group을 기준으로는 보장되지만 서로 다른 message group 간에는 당연히 보장이 안 된다. 참고로 FIFO에서는 최소한 한 개 이상의 message group을 사용해야만 한다.
  • FIFO에서는 message deduplication ID라는 것이 있는데 만약 특정 message deduplication ID를 가진 메시지를 큐에 보내는데 성공하면 같은 message dedeplication ID를 가진 메시지를 큐에 또 보낼 수는 있지만 5분 동안 큐가 전달하지는 않는다. SQS는 메시지가 수신되거나 삭제되더라도 이를 계속 트래킹한다. message deduplication ID말고 그냥 메시지 바디를 갖고 해시값을 도출해서 사용하는 content-based deduplication 기능도 있다.
  • FIFO 큐는 이름이 항상 .fifo로 끝나야 한다.

큐 타입은 큐 생성 시에 한번 정하고 나면 추후 수정할 수 없다

2. 설정값

Receive message wait time, enter a value. The range is from 0 to 20 seconds. The default value is 0 seconds, which sets short polling. Any non-zero value sets long polling.

(1) Visibility Timeout

큐에서 메시지가 컨슈머로 전달되었다고 해서 큐가 메시지를 바로 삭제하는 것은 아니다. 큐는 컨슈머가 메시지를 제대로 받고 제대로 처리했는지 알 수 없기 때문에 큐에서 메시지를 삭제하는 동작은 컨슈머가 메시지로 제대로 작업을 처리하고 난 이후에 스스로 수행해야 한다.

메시지는 크게 다음과 같은 3가지 동작에 의해 처리된다.
(1) 프로듀서에 의해 큐에 전송됨
(2) 컨슈머에 의해 큐로부터 수신됨
(3) 큐에서 삭제됨

이때 (1)과 (2) 사이를 stored 상태, (2)와 (3) 사이를 in flight 상태라고 한다.
이때 in flight 상태의 메시지는 다른 컨슈머에 의해 바로 중복 컨슘되면 안 되기 때문에 한번 컨슈머로 전송되고 in flight 상태에 있는 메시지는 Visibility Timeout 기간 동안 다른 컨슈머에 보이지 않는다. Visibility Timeout 기간 이후에는 그 사이에 메시지가 큐에서 삭제되지 못했다면 다른 컨슈머에 의해 보이게 되고 컨슘된다. 즉, 컨슈머로의 메시지 전달이 계속 실패하거나, 컨슈머의 작업 처리 시간이 너무 길다면 다른 컨슈머가 해당 메시지를 중복 컨슘하게 될 수 있는 것이다. 좀더 자세히 말하자면 컨슈머가 DeleteMessage 콜을 Visibility Timeout 전에 하지 않으면 메시지가 중복 컨슘되는 것이다.
(참고로 Standard Queue는 in flight 상태의 메시지를 최대 120,000 개, FIFP Queue는 최대 20,000개 갖고 있을 수 있다.)

따라서 내가 작성하는 애플리케이션이 메시지를 받아 작업을 처리하고, 메시지를 삭제하기까지 얼마나 걸릴지를 잘 생각해서 Visibility Timeout을 정해야 한다. 그렇지 않으면 다음과 같은 문제들이 생길 수 있다.

  • 보통 컨슈머 애플리케이션이 메시지를 처리하는데 10초가 걸리는데 Visibility Timeout이 15분인 경우
    : 첫 번째 컨슘 후 처리가 실패하면 다음 처리 때까지 너무 오랜 시간이 걸린다.
  • 보통 컨슈머 애플리케이션이 메시지를 처리하는데 2초가 걸리는데 Visibility Timeout이 2초인 경우
    : 컨슈머 애플리케이션이 미처 메시지를 처리하기도 전에 동일 메시지가 다른 컨슈머 애플리케이션에 의해 컨슘 및 처리되게 된다.

만약 내 컨슈머 애플리케이션이 메시지를 처리하고 삭제하기까지 걸리는 시간을 적절히 추론할 수 없다면 컨슈머 애플리케이션 동작 중에 동적으로 Visibility Timeout을 늘리는 방법을(?) 취해야한다.(ChangeMessageVisibilty를 메시지 처리 도중에 호출)

이러한 Visibility Timeout은 큐 전체 메시지에 대해 적용할 수도 있고 특정 메시지를 대상으로 적용할 수도 있다.(ChangeMessageVisibility)

(2) Message retention period

SQS가 큐에 메시지를 보관하는 기간(최대 14일로 설정 가능)

(3) Delivery delay

SQS가 큐가 받은 메시지를 컨슈머에게 전달하기 전까지의 지연 시간, 즉 이 시간이 지나기 전까지는 그 어떤 컨슈머도 메시지를 받지 못하는 것이다.

(4) Maximum Message Size

메시지의 최대 크기, 메시지 크기가 너무 크면 S3에 대량의 내용을 저장하고 메시지에는 해당 포인터만 담는 방법도 있다.

(5) Receive message wait time

SQS가 큐가 Receive 요청을 받았을 때 메시지가 이용 가능해질 때까지 기다리는 시간, 이에 관해서
(a) short polling
(b) long polling
이라는 개념을 알아야 한다.

(a) short polling은 ReceiveMessage 요청이 왔을 때, SQS가 즉시 그것을 이루고 있는 여러 서버들 중 몇 개만을 추려서(weighted random distribution에 근거) 해당 서버의 메시지만을 리턴하는 것이다. 그리고 그렇게 했을 때 메시지가 아무것도 없는 것으로 나와도 일단 응답을 준다. 따라서 특정 ReceiveMessage 요청은 모든 메시지를 리턴하지는 않을 수도 있다. 하지만 계속 이러한 요청을 반복하다보면 SQS는 모든 서버들의 메시지를 받을 수 있게 된다.

(b) long polling은 ReceiveMessage 요청이 왔을 때, SQS가 모든 서버를 뒤져서 메시지를 찾는다. 그래서 최소 한 개 이상의 메시지를 찾아야 응답을 주는데 대신 wait time이 지나면 빈 응답을 줄 수도 있다. long polling은 wait time 설정이 0보다 큰 경우 자동으로 활성화된다. 최대 long polling wait time은 20초이다. long polling은

  • Receive 요청 당시에 아무런 메시지가 없을 때 빈 응답을 주는 경우를 줄이고
  • 메시지가 있는데 빈 응답이 가는 경우를 방지해준다.(short polling은 메시지가 있어도 빈 응답을 줄 수도 있다)

(6) Enable content-based deduplication

SQS는 메시지 바디에 근거해서 자동으로 deduplication ID를 생성할 수 있다.

(7) Enable high thoughput FIFO

FIFO 큐의 처리량을 높일 때 쓰는 옵션으로 이 옵션을 설정하면 Deduplication scope이나 FIFO throughtput limit이 그에 맞게 자동 세팅된다. 이 자동 세팅되는 설정을 바꾸면 안 된다.

(8) Redrive allow policy

어느 소스 큐가 이 큐를 DLQ(dead-letter queue)로 쓸 수 있는지를 지정
Allow all(모든 큐가 이 큐를 DLQ로 사용 가능) / By queue(몇몇 지정된 큐만 이 큐를 DLQ로 지정 가능) / Deny all의 선택지가 있다. 여러 개의 큐가 하나의 DLQ를 공유하면서 쓸 수 있다. 소스큐와 DLQ의 타입(Standard vs. FIFO)은 동일해야 한다.

profile
성장의 기쁨

0개의 댓글