AI VIDEO BRIEFING
백그라운드 작업 처리 시스템 설계: 큐·트랜잭셔널 아웃박스·멱등성·데드레터 큐
회원가입 이메일 발송이라는 간단한 예시가 규모가 커지며 어디서 깨지는지를 단계별로 짚는다. 큐, 트랜잭셔널 아웃박스, 가시성 타임아웃, 멱등성, 데드레터 큐 개념을 정리했다.

핵심 메시지
쉽게 이해하기
이 영상은 백그라운드 작업 처리 시스템을 설계하면서, 단계마다 어디서 문제가 생기는지 보여 주는 방식으로 개념을 설명한다. 예시는 단순하다. 사용자가 모바일 앱에서 회원가입을 하면 계정이 생성되고 앱을 쓸 수 있게 되는 흐름이다.
버전 1은 순진한 방식이다. 사용자가 정보를 입력하고 제출하면 백엔드의 계정 설정 서비스가 계정을 만들어 DB에 저장하고, 곧바로 이메일 발송 서비스를 호출해 이메일을 보낸 뒤에야 가입 완료를 알린다. 로컬에서는 잘 되지만 현실에서는 이메일 서비스가 느린 날 2초가 걸리거나 아예 죽어 있을 수 있다. 이메일이 갈 때까지 기다리면 사용자는 '잠시만 기다려 주세요' 화면을 계속 봐야 하고, 더 나쁘게는 이메일이 실패하면 요청 전체가 실패한다.
버전 2는 큐를 추가한다. 백엔드는 이메일을 기다리지 않고 계정을 DB에 저장한 뒤 즉시 가입 완료를 알리고, 작업을 큐에 기록한다. 큐는 SQS 같은 도구가 관리하는 작업 대기열이며, 별도의 워커 그룹이 큐에서 작업을 꺼내 이메일을 보낸다. 이제 사용자는 밀리초 단위로 응답을 받는다. 다만 백엔드가 '계정 저장'과 '작업 큐 등록' 두 가지를 해야 하는데, 계정을 저장한 뒤 큐에 쓰기 전에 크래시가 나면 계정은 만들어졌는데 이메일은 영영 가지 않는다.
그 해법이 트랜잭셔널 아웃박스다. 큐에 직접 쓰는 대신, 계정과 동일한 DB 트랜잭션 안에서 작업을 '아웃박스 테이블'에 기록한다. 그리고 별도 프로세스가 아웃박스 테이블을 읽어 큐로 작업을 밀어 넣는다. 이렇게 하면 계정과 작업이 함께 저장되거나 둘 다 저장되지 않는다. 하지만 새로운 문제가 생긴다. 워커가 큐에서 작업을 집어 이메일을 보내던 중 크래시가 나면, 작업은 집어 든 순간 이미 큐에서 제거됐기 때문에 큐에도 없고 이메일도 안 간 상태가 된다.
버전 3은 작업이 완료되기 전까지 삭제하지 않는다. 좋은 큐는 가시성 타임아웃을 쓴다. 워커가 작업을 집으면 삭제하지 않고 예컨대 30초 동안 숨겨 두기만 한다. 워커는 이메일이 정말로 발송된 뒤에야 작업을 삭제한다. 워커가 크래시하면 작업이 큐에 다시 나타나 다른 워커가 넘겨받으므로 아무것도 유실되지 않는다.
주요 인사이트
- 가시성 타임아웃은 유실을 막는 대신 '최소 1회 전달(at-least-once)'이라는 성질을 만든다. 워커가 이메일을 보낸 뒤 작업을 삭제하기 직전에 크래시하면, 작업이 큐에 다시 나타나 두 번째 워커가 같은 이메일을 또 보낸다.
- 중복 환영 이메일을 막으려면 워커를 멱등(idempotent)하게 만들어야 한다. 각 작업은 고유 ID를 갖고, 워커는 작업을 마치면 그 ID를 기록해 이미 처리한 ID의 작업은 건너뛴다.
- 일부 작업은 이메일 주소가 유효하지 않거나 수신 불가라 그냥 실패한다. 재시도는 하되 무한정 할 수는 없고, 그렇다고 조용히 버려서도 안 된다.
- 버전 4는 실패 처리를 다룬다. 약 다섯 번 실패한 작업은 데드레터 큐로 옮긴다. 데드레터 큐는 계속 실패하는 작업을 세워 두는 '주차장'과 같아서, 엔지니어가 작업을 살펴 문제를 고치고 다시 실행할 수 있다.
- 핵심은 각 개선이 새로운 문제를 낳는다는 점이다. 큐가 응답 지연을 없애면 저장·등록의 원자성 문제가, 아웃박스가 이를 풀면 워커 크래시로 인한 유실이, 가시성 타임아웃이 이를 막으면 중복 전달이 생긴다. 설계는 이 연쇄를 하나씩 메우는 과정이다.
자주 묻는 질문
왜 회원가입 시 이메일을 동기적으로 보내면 안 되나?
이메일 서비스가 느린 날 2초가 걸리거나 죽어 있을 수 있기 때문이다. 발송을 기다리면 사용자는 대기 화면을 계속 봐야 하고, 이메일이 실패하면 가입 요청 전체가 실패한다.
트랜잭셔널 아웃박스는 어떤 문제를 해결하나?
계정 저장과 작업 큐 등록이 따로일 때, 계정만 저장되고 크래시가 나 이메일이 누락되는 문제를 막는다. 작업을 계정과 같은 DB 트랜잭션의 아웃박스 테이블에 기록하고 별도 프로세스가 이를 큐로 옮겨, 둘이 함께 저장되거나 함께 실패하도록 보장한다.
'최소 1회 전달'과 멱등성은 무슨 관계인가?
가시성 타임아웃 때문에 워커가 발송 후 삭제 직전에 크래시하면 같은 작업이 다시 처리돼 이메일이 중복 발송될 수 있다(최소 1회 전달). 이를 막으려면 각 작업에 고유 ID를 부여하고, 워커가 이미 처리한 ID는 건너뛰도록 멱등하게 만들어야 한다.
원문과 출처
이 글은 원본 영상의 자막을 바탕으로 한국어 독자를 위해 요약했습니다. 전체 맥락과 최신 정보는 원문에서 확인하세요.
YouTube 원본 영상 보기 ↗