Today I Learned
날짜
2025년 1월 31일 금요일
내용
SQS 큐의 중복 판단 기준
Amazon SQS에서 FIFO Queue에선 메시지의 중복 여부를 확인하는 방식이 2가지가 있다.
설정 방법 | 동작 방식 | 사용 예시 |
---|---|---|
자동 (Content-Based Deduplication) | 메시지 본문의 SHA-256 해시 값이 Deduplication ID로 설정됨 | 메시지 본문이 같으면 5분 이내에 중복 제거됨 |
사용자 지정 (MessageDeduplicationId) | 사용자가 직접 중복 제거 ID를 설정할 수 있음 | 메시지가 같아도 다른 ID를 부여하면 별도 메시지로 처리됨 |
카페24 API 웹훅은 변경된 데이터에 대한 간략한 정보만 들어온다. 웹훅에 관한 필요한 데이터만 처리해서 메시지를 작성하고 큐에 집어 넣는다. 따라서 별개의 웹훅이라도 본문이 같을 수 있다. 예를 들어 5분 간격으로 같은 스토어의 같은 상품 정보가 변경되었다고 하더라도 웹훅 정보, 샵 아이디, 몰 아이디, 상품 아이디 정도만 메시지에 담기므로 메시지가 동일해 보일 수 있다는 의미다. 이럴 경우 중복으로 처리되면 안되기 때문에 사용자 지정으로 설정해주었다.
메시지 그룹 내의 동시성 문제
웹훅 개선에서 핵심은 카페24 API 호출 제한으로 인해 요청이 실패하지 않도록 속도를 제어하는 것이다. 나는 이를 위해 두 가지 장치를 마련했는데 첫 번째는 메시지 그룹에서 메시지가 하나씩 처리된다는 점이고, 나머지는 헤더와 응답 코드를 이용한 재시도 코드다.
첫번째를 더 구체적으로 설명하면, 동일한 메시지 그룹에 있는 메시지는 동시에 2개 이상 처리될 수 없다는 뜻이다. A라는 메시지 그룹의 메시지 a,b,c가 들어있다고 가정하자. a가 처리되는 동안 b,c는 메시지 그룹에 가만히 있고 처리되지 않는다. a 메시지가 처리되어 삭제가 되고 나서야 다음 순서인 메시지 b가 처리 된다. 메시지 c는 메시지 b가 처리 되고 난 후에야 된다.
그런데 큐에 메시지가 쌓이면 동시다발적으로 상태머신 수십 개가 호출된다. 상태머신이 평균 0.3초 정도 작동하니, 1초에 많아야 3~4개의 상태머신만 동작해야 할텐데.. 이해가 잘 되지 않았다. 원인은 메시지 트리거가 step functions가 아닌 람다라는 점이었다. 하나의 메시지가 처리 완료되었다고 판단되는 시점은 상태 머신까지 완료되어 종료된 시점이 아니라 트리거 람다가 종료된 시점이다.
메시지\시간 | a | b | c |
---|---|---|---|
0s | 트리거 함수 호출 | ||
0.1s | 상태머신 호출 | ||
0.2s | 트리거 함수 종료/상태머신 진행중 | 트리거 함수 호출 | |
0.3s | 상태머신 진행중 | 상태머신 호출 | |
0.4s | 상태머신 진행중 | 트리거 함수 종료/상태머신 진행중 | 트리거 함수 호출 |
0.5s | 상태머신 진행중 | 상태머신 진행중 | 상태머신 호출 |
0.6s | 상태머신 진행중 | 상태머신 진행중 | 트리거 함수 종료/상태머신 진행중 |
0.7s | 상태머신 진행중 | 상태머신 진행중 | |
0.8s | 상태머신 진행중 | 상태머신 진행중 | |
0.9s | 상태머신 진행중 | ||
1.0s | 상태머신 진행중 |
0.6초 시점에는 상태머신을 기준으로는 동시에 3개의 메시지가 처리되고 있다. 하지만 ‘트리거 함수’를 기준으로 하면 항상 하나씩만 처리된다. SQS 큐에 설정된 트리거가 ‘상태머신으로 데이터를 처리하고 저장하기’가 아니라 ‘상태머신 호출하기’ 라서 이런 상태였다.
결국 메시지 그룹의 동시성 제한은 속도 조절에 아무 역할을 할 수 없다. “요청이 너무 많아 카페24에서 429 응답코드를 반환하면 1초 Sleep하고 다시 요청 보내면 되지않냐”고 생각할 수 있지만, 최악의 경우를 고려해야 한다.
요청이 몰려 속도 제한이 걸려있는 상태에서 1000개의 주문 데이터 웹훅이 들어왔다고 가정하자. 초당 100개의 트리거 람다가 호출되면 1초 후 상태머신 100개가 가동중이다. 상태머신 내부의 람다가 호출되고 현재 속도 제한에 걸려 초당 5개씩 밖에 처리하지 못한다고 가정해보자.그럼 가장 오래걸리는 상태머신은 12초나 sleep하고 있고 그 기간 동안 내부 람다도 호출되고 있다. 람다는 호출 시간동안 비용이 부과되므로 비용이 증가한다는 뜻이다. 이를 해결할 방법이 없을까…
회고
카페24 API가 요청 속도 제한에 걸리는 상황을 테스트하려고 한다. 아무리 요청을 보내도 제한에 걸리지 않는다. 4000개를 보냈는데 아무 문제가 없다. 당신들 뭐야.