메시지를 잃지 않으려면 (Delivery Guarantees)
어디까지 읽었는지 기록하는 시점을 언제로 잡느냐가 유실과 중복을 가릅니다. 처리하기 전에 먼저 기록하면 중간에 죽었을 때 그 메시지를 다시는 읽지 못하고(at-most-once), 처리한 뒤에 기록하면 죽었을 때 같은 메시지를 한 번 더 읽습니다(at-least-once). 카프카는 대개 후자를 택하고, 중복을 견디도록 처리 쪽을 멱등하게 만듭니다.
01메시지를 잃지 않으려면 (Delivery Guarantees)
개념 한눈에 보기커밋 먼저 · 잃을 수 있다 (at-most-once)
주문 네 건이 쌓여 있고, 컨슈머가 B를 읽으려는 참입니다. 아직 아무것도 커밋하지 않았습니다.
이 방식은 읽자마자 먼저 커밋합니다. B까지 처리했다는 기록이 남고, 다음에 읽을 자리는 C가 됩니다.
그런데 B를 처리하던 중에 컨슈머가 죽습니다. 결제도, 저장도 아직 안 된 상태입니다.
재시작하면 커밋된 자리인 C부터 읽습니다. B는 아무도 처리하지 않았는데 영영 건너뛰어집니다.
처리 먼저 · 중복될 수 있다 (at-least-once)
같은 상황에서 순서만 바꿔 봅니다. 커밋은 아직 하지 않았습니다.
이번엔 B를 먼저 처리합니다. 커밋을 하지 않았으므로 다음에 읽을 자리는 B 그대로입니다.
처리를 끝낸 직후, 커밋하기 전에 컨슈머가 죽습니다.
재시작하면 커밋된 자리가 없어 B부터 다시 읽습니다. 잃지는 않았지만 중복 처리됩니다.
그래서 실무는 이쪽을 택하고, 같은 주문을 두 번 처리해도 결과가 같도록(멱등) 만듭니다. 주문 번호로 중복을 걸러내는 식입니다.
02 쉽게 이해하기
For Everyone커밋과 처리 중 무엇을 먼저 하느냐가 유실과 중복을 가릅니다. 먼저 커밋하면 장애가 난 메시지가 건너뛰어지고, 먼저 처리하면 같은 메시지를 한 번 더 읽습니다.
커밋을 먼저 하면 처리 도중 죽은 메시지는 영영 건너뜁니다(유실).
처리를 먼저 하면 커밋 전에 죽었을 때 재시작 후 같은 메시지를 다시 처리합니다(중복).
둘 다 없애려면 처리와 커밋이 하나의 트랜잭션이어야 하는데 비용이 큽니다.
그래서 실무에서는 at-least-once 를 택하고, 같은 메시지를 두 번 처리해도 결과가 같도록(멱등) 만드는 쪽이 일반적입니다.
- –결제·주문처럼 유실이 치명적인 처리 설계
- –중복 처리에 대비한 멱등 키 설계
- –커밋 주기와 장애 복구 시간의 트레이드오프 판단
03 자주 묻는 질문
FAQ메시지를 잃지 않으려면 (Delivery Guarantees)란 무엇인가요?+
어디까지 읽었는지 기록하는 시점을 언제로 잡느냐가 유실과 중복을 가릅니다. 처리하기 전에 먼저 기록하면 중간에 죽었을 때 그 메시지를 다시는 읽지 못하고(at-most-once), 처리한 뒤에 기록하면 죽었을 때 같은 메시지를 한 번 더 읽습니다(at-least-once). 카프카는 대개 후자를 택하고, 중복을 견디도록 처리 쪽을 멱등하게 만듭니다.
메시지를 잃지 않으려면 (Delivery Guarantees)은(는) 어디에 사용하나요?+
결제·주문처럼 유실이 치명적인 처리 설계, 중복 처리에 대비한 멱등 키 설계, 커밋 주기와 장애 복구 시간의 트레이드오프 판단
메시지를 잃지 않으려면 (Delivery Guarantees)를 쉽게 비유하면?+
커밋과 처리 중 무엇을 먼저 하느냐가 유실과 중복을 가릅니다. 먼저 커밋하면 장애가 난 메시지가 건너뛰어지고, 먼저 처리하면 같은 메시지를 한 번 더 읽습니다.
