SQS 배치 작업으로 전환하면 성능과 비용이 향상되는 방법
Source: Dev.to
죄송합니다만, 번역을 진행하려면 실제 기사 본문이 필요합니다. 위에 제공해 주신 링크의 내용을 복사해서 여기 붙여 주시면, 해당 텍스트를 한국어로 번역해 드리겠습니다.
Abstract
이 게시물에서는 개별 SendMessage 호출을 Batch SendMessage 작업으로 리팩터링함으로써 애플리케이션 성능을 크게 향상시키고 IOPS 사용량을 낮춰 SQS 청구 비용을 절감할 수 있는 방법을 탐구합니다.
아이디어
DataDog으로 Golang 애플리케이션을 모니터링할 때, SQS 메시지 전송을 상세히 측정할 수 있습니다. 기존의 루프 기반 전송 방식과 배치 전송 방식을 비교하면, 타이밍, 네트워크 호출, 그리고 리소스 사용량에서 명확한 차이를 확인할 수 있습니다.
전체 Datadog SQS 추적은 모든 언어에서 지원되지 않음
이 서비스에 다음 환경 변수를 설정하면 전체 페이로드 태깅을 활성화할 수 있습니다:
DD_TRACE_CLOUD_REQUEST_PAYLOAD_TAGGING=all
DD_TRACE_CLOUD_RESPONSE_PAYLOAD_TAGGING=all
문서:
Golang의 경우 Datadog 속성 태그를 활용하여 페이로드 메타데이터를 검사할 수 있습니다.
정규 SQS 메시지 전송 작업
메시지를 하나씩 전송하면 여러 번의 네트워크 호출과 추가 오버헤드가 발생합니다. 아래 추적 다이어그램은 루프 연산을 사용할 때 타이밍이 어떻게 보이는지 보여줍니다.
예시: 7개의 메시지를 개별적으로 전송하는 데 175 ms가 걸렸으며 7개의 별도 HTTP 요청이 사용되었습니다. 첫 번째 호출은 DNS 조회와 연결 설정 때문에 일반적으로 타이밍을 가장 많이 차지합니다.
서비스가 동일한 K8s 클러스터 내에서 실행되므로 실험이 깨끗하고 추가적인 오버헤드가 없다고 가정할 수 있습니다.
배치로 메시지 전송
AWS SQS는 배치당 최대 10개의 메시지 전송을 허용합니다. 2개의 배치에 20개의 메시지를 전송하면 상당한 효율 향상을 확인할 수 있습니다:
- 전송된 메시지 수가 3배 증가했습니다.
- HTTP 요청 수가 10배 감소했습니다.
- 전체 처리 시간이 ≈ 3배 단축되었습니다.

응답 예시
배치 전송이 수행될 때, 응답에는 각 메시지에 대한 상태와 오류가 포함됩니다. 배치는 부분적으로 성공할 수 있으며, 응답을 파싱하면 실패를 효율적으로 재시도하거나 처리할 수 있습니다.
{
"Successful": [
{ "ID": "0", "MessageID": "655f3404-fbe4-4c51-8868-b5c604bd5f6d", "Error": null },
{ "ID": "1", "MessageID": "daf36653-9abb-490b-b620-608efa24a219", "Error": null },
{ "ID": "2", "MessageID": "93f4dcfd-0500-4076-90f2-3b880b32c943", "Error": null },
{ "ID": "3", "MessageID": "f6c7b079-98f5-4290-b293-2ac6e43ed6f2", "Error": null },
{ "ID": "4", "MessageID": "2b4a96bc-b4ec-4711-9473-d887dd3213f7", "Error": null },
{ "ID": "5", "MessageID": "1bd30cd9-f9c1-4b47-8d6d-2e23ce771841", "Error": null },
{ "ID": "6", "MessageID": "8eed75ef-2563-442e-a191-6b3dff29d635", "Error": null },
{ "ID": "7", "MessageID": "c65a36ce-7ce0-444c-9974-96648dcae0ea", "Error": null },
{ "ID": "8", "MessageID": "75379265-5f9-4a60-8c3a-0537cffdaa80", "Error": null },
{ "ID": "9", "MessageID": "59239903-d4d9-498f-9a08-6d7d7ae8beba", "Error": null },
{ "ID": "10", "MessageID": "9a614c58-113b-487d-a8f1-7509f93b42f9", "Error": null },
{ "ID": "11", "MessageID": "1077de5c-8f0f-4d5b-a0fe-dca45712bfdf", "Error": null },
{ "ID": "12", "MessageID": "8b0f5836-0e01-4a88-9793-4bac2a6d879a", "Error": null }
],
"Failed": []
}
AWS Console behavior
Batch sending does not change how messages appear in SQS. Each message is stored individually, so consumers don’t need any changes to handle batches.

The same messages, with the same structure, are posted and visible in SQS. Other optimization techniques can be applied to adjust consumer batch size when polling messages from SQS.
Golang 구현 예시
entry := &sqs.SendMessageBatchRequestEntry{
Id: aws.String(fmt.Sprintf("%d", i+idx)), // Unique ID within batch
MessageBody: aws.String(string(b)),
}
if taskConfig.MessageGroupId != "" {
entry.SetMessageGroupId(taskConfig.MessageGroupId)
}
if taskConfig.MessageDeduplicationId != "" {
entry.SetMessageDeduplicationId(taskConfig.MessageDeduplicationId)
}
if taskConfig.DelaySeconds > 0 {
entry.SetDelaySeconds(taskConfig.DelaySeconds)
}
entries = append(entries, entry)
}
// ...
type BatchResult struct {
Successful []BatchResultEntry
Failed []BatchResultEntry
}
코드 예시
// BatchResultEntry represents a single entry in a batch result
type BatchResultEntry struct {
ID string
MessageID string
Error error
}
// Send batch
input := &sqs.SendMessageBatchInput{
QueueUrl: stp.url,
Entries: entries,
}
output, err := stp.c.SendMessageBatchWithContext(ctx, input)
if err != nil {
err = handleSqsErrors(err)
// Mark all entries in this batch as failed
for idx := range batch {
result.Failed = append(result.Failed, BatchResultEntry{
ID: fmt.Sprintf("%d", i+idx),
Error: err,
})
}
continue
}
전용 메시지 세부 정보
정확히 이 messageID가 배치 성공 응답 섹션에 반환되었습니다.
확인 및 최적화할 추가 사항
중복 제거 기법
메시지를 전송하기 전에 중복 제거를 수행하십시오. 이렇게 하면 SQS IOPS 사용량이 감소하고 처리 지연 시간이 줄어들며 소비자 측 부하가 감소합니다. 또한 불필요한 스토리지 읽기, 재작성 등을 방지합니다.
분산 추적 프레임워크가 SQS 배치 슬롯을 사용할 수 있음
일부 분산 추적 프레임워크는 SQS와 같은 비동기 전송을 통해 메타 정보를 전파합니다. 이를 사용 중이라면 통합을 확인하십시오—최대 배치 크기에 영향을 줄 수 있습니다.
- Datadog은 추적과 함께 메타 정보를 전파하기 위해 하나의 배치 요소를 사용하며, 이는 동일한 추적에 소비되고 적용됩니다.
- AWS X‑Ray(AWS 고유 기술)는 SQS 배치에서 어떤 슬롯도 사용하지 않으며, 스팬/추적 정보를 UDP 서버를 통해 전송합니다.
제한 사항
- 메시지 크기 페이로드: 1 MiB
- 배치 크기: 10 메시지
- 페이로드 직렬화: JSON
결론
- 전체 처리 시간을 크게 감소시킵니다.
- 네트워크 왕복 횟수를 줄입니다.
- SQS 청구 비용을 낮춥니다 (API 호출 수 감소, 대략 10배 감소).

