Oh My Algorithm
Concept Guideat-least-once · at-most-once

메시지를 잃지 않으려면 (Delivery Guarantees)

어디까지 읽었는지 기록하는 시점을 언제로 잡느냐가 유실과 중복을 가릅니다. 처리하기 전에 먼저 기록하면 중간에 죽었을 때 그 메시지를 다시는 읽지 못하고(at-most-once), 처리한 뒤에 기록하면 죽었을 때 같은 메시지를 한 번 더 읽습니다(at-least-once). 카프카는 대개 후자를 택하고, 중복을 견디도록 처리 쪽을 멱등하게 만듭니다.

01메시지를 잃지 않으려면 (Delivery Guarantees)

커밋 먼저 · 잃을 수 있다 (at-most-once)

주문 네 건이 쌓여 있고, 컨슈머가 B를 읽으려는 참입니다. 아직 아무것도 커밋하지 않았습니다.

이 방식은 읽자마자 먼저 커밋합니다. B까지 처리했다는 기록이 남고, 다음에 읽을 자리는 C가 됩니다.

그런데 B를 처리하던 중에 컨슈머가 죽습니다. 결제도, 저장도 아직 안 된 상태입니다.

재시작하면 커밋된 자리인 C부터 읽습니다. B는 아무도 처리하지 않았는데 영영 건너뛰어집니다.

주문 파티션🧾 A🧾 B🧾 C🧾 D먼저 온 주문 · 나중에 온 주문컨슈머다음에 읽을 자리아직 처리 안 함
1 / 4

정리

커밋을 먼저 하면 최대 한 번만 처리됩니다(at-most-once). 빠르지만 장애가 곧 유실입니다.

처리 먼저 · 중복될 수 있다 (at-least-once)

같은 상황에서 순서만 바꿔 봅니다. 커밋은 아직 하지 않았습니다.

이번엔 B를 먼저 처리합니다. 커밋을 하지 않았으므로 다음에 읽을 자리는 B 그대로입니다.

처리를 끝낸 직후, 커밋하기 전에 컨슈머가 죽습니다.

재시작하면 커밋된 자리가 없어 B부터 다시 읽습니다. 잃지는 않았지만 중복 처리됩니다.

그래서 실무는 이쪽을 택하고, 같은 주문을 두 번 처리해도 결과가 같도록(멱등) 만듭니다. 주문 번호로 중복을 걸러내는 식입니다.

주문 파티션🧾 A🧾 B🧾 C🧾 D먼저 온 주문 · 나중에 온 주문컨슈머다음에 읽을 자리아직 처리 안 함
1 / 5

정리

유실과 중복 중 하나는 감수해야 합니다. 대개 중복이 다루기 쉬워 at-least-once + 멱등 처리를 씁니다.

02 쉽게 이해하기

For Everyone
🔑핵심 동작

커밋과 처리 중 무엇을 먼저 하느냐가 유실과 중복을 가릅니다. 먼저 커밋하면 장애가 난 메시지가 건너뛰어지고, 먼저 처리하면 같은 메시지를 한 번 더 읽습니다.

💡쉽게 말하면

커밋을 먼저 하면 처리 도중 죽은 메시지는 영영 건너뜁니다(유실).

처리를 먼저 하면 커밋 전에 죽었을 때 재시작 후 같은 메시지를 다시 처리합니다(중복).

둘 다 없애려면 처리와 커밋이 하나의 트랜잭션이어야 하는데 비용이 큽니다.

그래서 실무에서는 at-least-once 를 택하고, 같은 메시지를 두 번 처리해도 결과가 같도록(멱등) 만드는 쪽이 일반적입니다.

📍어디에 쓰나
  • 결제·주문처럼 유실이 치명적인 처리 설계
  • 중복 처리에 대비한 멱등 키 설계
  • 커밋 주기와 장애 복구 시간의 트레이드오프 판단

03 자주 묻는 질문

FAQ
메시지를 잃지 않으려면 (Delivery Guarantees)란 무엇인가요?+

어디까지 읽었는지 기록하는 시점을 언제로 잡느냐가 유실과 중복을 가릅니다. 처리하기 전에 먼저 기록하면 중간에 죽었을 때 그 메시지를 다시는 읽지 못하고(at-most-once), 처리한 뒤에 기록하면 죽었을 때 같은 메시지를 한 번 더 읽습니다(at-least-once). 카프카는 대개 후자를 택하고, 중복을 견디도록 처리 쪽을 멱등하게 만듭니다.

메시지를 잃지 않으려면 (Delivery Guarantees)은(는) 어디에 사용하나요?+

결제·주문처럼 유실이 치명적인 처리 설계, 중복 처리에 대비한 멱등 키 설계, 커밋 주기와 장애 복구 시간의 트레이드오프 판단

메시지를 잃지 않으려면 (Delivery Guarantees)를 쉽게 비유하면?+

커밋과 처리 중 무엇을 먼저 하느냐가 유실과 중복을 가릅니다. 먼저 커밋하면 장애가 난 메시지가 건너뛰어지고, 먼저 처리하면 같은 메시지를 한 번 더 읽습니다.