이벤트 기반 아키텍처: Kafka vs RabbitMQ 실무 비교 및 선택 기준
📌 핵심 요약
- 강한 결합(HTTP)을 끊어내기 위한 비동기 이벤트 처리의 필요성
- RabbitMQ(메시지 브로커): 복잡한 라우팅과 작업 큐에 최적화 (Smart Broker)
- Kafka(이벤트 스트리밍): 대용량 데이터 처리와 로그 저장에 최적화 (Dumb Broker)
- 실무 아키텍처링 시 고려해야 할 순서 보장과 멱등성(Idempotency) 이슈
마이크로서비스(MSA)가 도입되면서 서비스 간의 통신 방식이 중요해졌습니다. A 서비스가 B 서비스를 호출할 때, HTTP(REST) 같은 동기 방식을 사용하면 A는 B가 응답할 때까지 기다려야 합니다. B가 죽으면 A도 같이 느려지거나 죽습니다.
이 강한 결합(Tight Coupling)을 끊기 위해 우리는 중간에 중개자(Broker)를 두고 메시지를 던져놓는 비동기 이벤트 기반 아키텍처(EDA)를 사용합니다. 이때 가장 많이 고민하는 두 가지 선택지, RabbitMQ와 Kafka의 결정적 차이를 파헤쳐 봅니다.
1. 기본 개념: 전화 vs 이메일
이해를 돕기 위해 비유를 들어보겠습니다.
- HTTP (REST): 전화 통화와 같습니다. 상대방이 전화를 받을 때까지 기다려야 하고, 통화 중에는 다른 일을 못 합니다. 즉각적인 응답이 필요할 때 씁니다.
- Message Queue (Kafka/RabbitMQ): 이메일이나 슬랙과 같습니다. 나는 메시지를 보내놓고 내 할 일을 합니다. 상대방은 자기가 편할 때 메시지를 확인하고 처리합니다.
2. RabbitMQ: "똑똑한 우체부" (Smart Broker)
RabbitMQ는 전통적인 메시지 브로커입니다. 메시지를 받아서 적절한 소비자(Consumer)에게 배달해 주고, 배달이 완료되면(Ack) 메시지를 삭제합니다.
특징 및 장점
- 복잡한 라우팅: Exchange라는 기능을 통해 메시지를 특정 큐로 보내거나(Direct), 여러 큐에 뿌리거나(Fanout), 패턴에 맞춰 보내는(Topic) 기능이 매우 강력합니다.
- 신뢰성: 메시지 전달 보장이 강력하며, 소비자가 처리를 못 하면 다시 큐에 넣거나 Dead Letter Queue로 보낼 수 있습니다.
- 휘발성: 기본적으로 소비된 메시지는 사라집니다. (이벤트 저장소가 아님)
3. Apache Kafka: "거대한 로그 파일" (Dumb Broker)
Kafka는 메시지 큐라기보다는 이벤트 스트리밍 플랫폼입니다. 메시지를 배달해 주는 것이 목적이 아니라, 메시지를 파일에 기록(Log)하고 소비자가 알아서 읽어가게 둡니다.
특징 및 장점
- 압도적인 처리량(Throughput): 디스크의 순차 저장(Sequential I/O) 방식을 사용하여 초당 수백만 건의 이벤트를 처리합니다.
- 영속성(Persistence): 소비자가 메시지를 읽어가도 삭제되지 않습니다. 설정된 기간(예: 7일) 동안 보관되므로, 나중에 다시 처음부터 읽을 수 있습니다(Replay).
- 단순한 라우팅: RabbitMQ 같은 복잡한 라우팅 기능이 없습니다. 그냥 토픽(Topic)에 쌓고 읽어갈 뿐입니다.
4. 비교 요약표 (면접 필수)
| 구분 | RabbitMQ | Apache Kafka |
|---|---|---|
| 설계 철학 | Smart Broker, Dumb Consumer (브로커가 똑똑함) |
Dumb Broker, Smart Consumer (소비자가 알아서 읽어감) |
| 처리량 | 높음 (수만 TPS) | 매우 높음 (수십~수백만 TPS) |
| 메시지 보관 | 소비(Ack) 즉시 삭제 | 설정 기간 동안 디스크에 보관 |
| 추천 용도 | 복잡한 라우팅, 작업 큐, 실시간 메시징 | 로그 수집, 스트림 처리, 빅데이터 파이프라인 |
5. 주의사항: "순서"와 "중복"
이벤트 시스템을 도입할 때 반드시 해결해야 할 난제가 있습니다.
⚠️ 멱등성 (Idempotency) 보장 필수
네트워크 문제로 인해 메시지가 두 번 전송(At-least-once)될 수 있습니다. "결제 요청" 이벤트가 두 번 오더라도, 실제 결제는 한 번만 이루어지도록 코드를 작성해야 합니다. (예: 결제 ID로 중복 체크)
또한, Kafka는 파티션(Partition) 내에서는 순서를 보장하지만, 여러 파티션을 사용할 경우 전체 순서를 보장하지 않습니다. 순서가 중요한 로직(예: 재고 차감 -> 결제 완료)은 반드시 같은 파티션 키를 사용해야 합니다.
6. 결론
"대용량 데이터 스트리밍과 로그 수집이 필요하다면 Kafka, 복잡한 메시지 라우팅과 즉각적인 작업 처리가 필요하다면 RabbitMQ"가 정답에 가깝습니다.
최근에는 MSA 환경에서 데이터 동기화(CDC)나 이벤트 소싱 용도로 Kafka가 표준처럼 쓰이고 있지만, 단순한 비동기 작업 처리(이메일 발송 등)에는 RabbitMQ가 훨씬 가볍고 운영하기 쉽습니다. 도구의 특성을 이해하고 적재적소에 배치하는 것이 아키텍트의 역량입니다.