RabbitMQ vs Kafka
MSA 환경에서는 서비스 간 결합도를 낮추고 비동기 통신을 구현하기 위해 메시지 브로커를 사용할 수 있다.
대표적인 기술로 RabbitMQ와 Apache Kafka가 있다.
두 기술 모두 Producer가 메시지를 발행하고 Consumer가 이를 비동기로 처리하도록 만들 수 있기 때문에 비슷해 보이지
만, 출발점과 핵심 설계 철학이 다르다.
간단하게 정리하면 다음과 같다.
RabbitMQ는 메시지를 전달하고 처리하는 Message Broker에서 출발했고, Kafka는 이벤트를 저장하고 다시 읽을 수 있는 Distributed Log에서 출발했다.
최근에는 RabbitMQ에 Stream이 추가되고 Kafka에도 Queue Semantic이 추가되면서 기능적으로 겹치는 부분이 많아졌지만, 두 시스템의 기본 구조를 이해하면 어떤 상황에서 무엇을 선택해야 하는지 판단하기 쉽다.
1. RabbitMQ란?
RabbitMQ는 메시지를 Producer로부터 Consumer에게 안정적으로 전달하고 처리하기 위한 메시지 브로커이다.
기본적인 구조는 다음과 같다.
Producer
│
▼
Exchange
│
│ Binding
▼
Queue
│
▼
Consumer
Producer가 Queue에 직접 메시지를 전달하는 것이 아니라 일반적으로 Exchange에 메시지를 발행한다.
Exchange는 Routing Key와 Binding 규칙을 이용하여 메시지를 적절한 Queue로 전달한다.
예를 들어 다음과 같은 이벤트가 있다고 하자.
hub.inventory.low
order.created
payment.completed
Exchange에 각각의 Queue를 연결할 수 있다.
┌─> notification.queue
Producer ─> Exchange
├─> order.queue
└─> payment.queue
어떤 메시지를 어떤 Queue로 전달할지는 Binding을 통해 결정한다.
Exchange 종류
대표적으로 다음과 같은 Exchange가 있다.
| Exchange | 특징 |
| Direct | Routing Key가 정확하게 일치하는 Queue로 전달 |
| Topic | *, # 등의 패턴을 이용하여 Routing |
| Fanout | 연결된 모든 Queue에 전달 |
| Headers | Header 정보를 기준으로 Routing |
예를 들어 Topic Exchange에서
hub.inventory.low
라는 Routing Key를 발행하고
hub.*
와 Binding된 Queue가 있다면 해당 Queue가 메시지를 받을 수 있다.
즉, RabbitMQ는 Broker가 메시지의 Routing을 담당한다.
2. Kafka란?
Kafka는 단순히 메시지를 전달하는 시스템보다는 대규모 이벤트를 지속적으로 저장하고 처리하기 위한 분산 이벤트 스트리밍 플랫폼에 가깝다.
Kafka의 핵심 구조는 다음과 같다.
Producer
│
▼
Topic
┌───────┬───────┬───────┐
│ P0 │ P1 │ P2 │
└───────┴───────┴───────┘
│ │ │
▼ ▼ ▼
Consumer Group
Kafka의 Topic은 여러 개의 Partition으로 나뉜다.
각 Partition은 순서가 있는 Append-Only Log이다.
Partition 0
offset
0 1 2 3
[event] [event] [event] [event]
새로운 이벤트는 기존 데이터를 변경하는 것이 아니라 로그의 끝에 계속 추가된다.
그리고 각각의 이벤트에는 Offset이 부여된다.
Consumer는 Offset을 이용하여
"내가 어디까지 읽었는가?"
를 관리한다.
따라서 이전 Offset으로 이동하면 과거 이벤트를 다시 읽는 Replay도 가능하다.
3. 가장 중요한 차이: Queue vs Log
RabbitMQ와 Kafka를 이해할 때 가장 중요한 차이이다.
RabbitMQ
RabbitMQ Queue에서 메시지는 기본적으로 처리해야 하는 하나의 작업 단위이다.
Queue
[A] [B] [C] [D]
│
▼
Consumer
A 처리 완료 → ACK
Consumer가 메시지를 정상적으로 처리하고 ACK를 보내면 해당 메시지는 Queue에서 제거된다.
즉,
메시지 생성
↓
Queue 대기
↓
Consumer 전달
↓
처리
↓
ACK
↓
Queue에서 제거
라는 생명주기를 가진다.
그래서 RabbitMQ에서는
"이 메시지를 누가 처리할 것인가?"
가 중요하다.
Kafka
Kafka의 메시지는 Queue의 작업이라기보다는 Log에 기록된 Event이다.
Consumer가 메시지를 읽었다고 해서 메시지가 삭제되지 않는다.
Topic
0 1 2 3 4
[A] [B] [C] [D] [E]
↑
Consumer Offset
Consumer는 현재 자신이 어디까지 읽었는지만 관리한다.
메시지는 Consumer의 처리 여부와 별개로 Kafka의 Retention Policy에 따라 일정 기간 보관된다.
따라서 다른 Consumer가 동일한 이벤트를 다시 읽을 수도 있다.
즉 Kafka에서는
"이 이벤트를 어떻게 저장하고 여러 Consumer가 어떻게 읽을 것인가?"
가 중요하다.
4. Consumer 처리 방식
RabbitMQ
RabbitMQ에서는 여러 Consumer가 하나의 Queue를 소비할 수 있다.
┌─ Consumer A
Queue ────────┼─ Consumer B
└─ Consumer C
메시지는 Consumer들에게 분배된다.
Message 1 → Consumer A
Message 2 → Consumer B
Message 3 → Consumer C
따라서 작업을 여러 Worker에게 분산하는 Work Queue 구조를 만들기 좋다.
Kafka
Kafka의 일반적인 Consumer Group에서는 Partition을 기준으로 Consumer에게 작업을 분배한다.
Topic
Partition 0 ── Consumer A
Partition 1 ── Consumer B
Partition 2 ── Consumer C
하나의 Consumer Group 안에서는 일반적으로 하나의 Partition을 동시에 하나의 Consumer가 담당한다.
따라서 Partition이 3개인데 Consumer를 10개 실행하면 모든 Consumer가 동시에 데이터를 처리하는 것은 아니다.
Partition = 3
Consumer = 10
실제로 동시에 처리 가능한 Consumer ≈ 3
그래서 Kafka에서는 Partition 설계가 병렬 처리 성능과 밀접하게 연결된다.
5. 메시지 Routing
RabbitMQ의 대표적인 강점 중 하나가 Broker-side Routing이다.
RabbitMQ에서는
Producer
↓
Exchange
↓
Binding
↓
Queue
구조를 통해 Broker가 메시지를 분배한다.
예를 들어
order.created
order.cancelled
payment.completed
라는 이벤트가 있을 때
order.*
와 같은 패턴을 이용할 수도 있다.
Producer는 단순히 이벤트를 발행하고 어떤 Consumer가 사용할지는 Binding으로 관리할 수 있다.
반면 Kafka는 기본적으로 Producer가 Topic과 Partition을 기준으로 이벤트가 저장될 위치를 결정한다.
Producer
↓
Topic
↓
Partition
따라서 RabbitMQ처럼 Exchange + Binding을 이용한 세밀한 Broker-side Routing이 핵심 구조는 아니다.
6. 실패 처리
메시지 기반 시스템에서는 Consumer가 항상 성공한다는 보장이 없다.
예를 들어
결제 완료 이벤트
↓
알림 서비스
↓
외부 SMS API 장애
와 같은 상황이 발생할 수 있다.
RabbitMQ에서는 메시지 단위로
ACK
NACK
Retry
Dead Letter Queue
TTL
등을 활용할 수 있다.
대표적인 구조가 다음과 같다.
Main Queue
│
▼
Consumer
│
실패
│
▼
Retry / DLQ
특정 메시지만 재시도하거나 계속 실패하는 메시지를 Dead Letter Queue로 분리하기 좋다.
Kafka에서도 실패 처리와 재시도 구조를 구현할 수 있지만, 기본 설계의 중심은 개별 작업의 생명주기 관리보다는 로그와
Consumer의 읽기 위치 관리에 있다.
7. 메시지를 다시 읽어야 한다면?
전통적인 RabbitMQ Queue에서는 ACK가 완료되면 메시지가 제거된다.
따라서
어제 발생한 이벤트를 처음부터 다시 처리하고 싶다.
와 같은 요구에는 기본 Queue 모델이 적합하지 않다.
Kafka는 메시지가 Retention 기간 동안 유지되기 때문에 Offset을 되돌려 다시 읽을 수 있다.
현재
0 1 2 3 4 5 6
↑
Offset 이동
0 1 2 3 4 5 6
↑
→ 다시 처리
이러한 특징 때문에 Kafka가 이벤트 스트리밍, 로그 수집, 이벤트 소싱, 데이터 파이프라인 등에 많이 사용된다.
다만 현재 RabbitMQ에도 Stream이 존재하기 때문에
"RabbitMQ는 무조건 Replay가 불가능하다."
라고 이해하면 안 된다.
RabbitMQ Stream은 Append-Only Log 구조와 Offset 기반 소비를 제공하기 때문에 Kafka와 유사한 스트리밍 워크로드도 처리할 수 있다.
8. RabbitMQ Stream과 Kafka
과거에는
RabbitMQ = Queue
Kafka = Stream
으로 구분해도 어느 정도 맞았다.
하지만 현재는 그렇게 단순하게 구분하기 어렵다.
RabbitMQ에는 Stream이 존재한다.
RabbitMQ Stream 역시
Append-Only Log
Offset
Retention
Replay
등의 개념을 지원한다.
반대로 Kafka도 Queue 형태의 워크로드를 지원하는 방향으로 확장되고 있다.
따라서 두 기술의 기능 영역은 점점 겹치고 있다.
그럼에도 중요한 차이는 어떤 문제를 중심으로 설계되었는가이다.
RabbitMQ
메시지를 어떻게 전달하고 처리할 것인가?
Kafka
이벤트를 어떻게 저장하고 읽을 것인가?
9. RabbitMQ vs Kafka 비교
| 구분 | RabbitMQ | Kafka |
| 기본 철학 | Message Broker | Distributed Event Log |
| 핵심 단위 | Message / Queue | Event / Topic / Partition |
| 메시지 소비 | ACK 후 Queue에서 제거 | Retention 기간 동안 유지 |
| 소비 위치 | Broker가 전달 상태 관리 | Consumer Offset 기반 |
| Routing | Exchange + Binding | Topic + Partition 중심 |
| 재처리 | 일반 Queue에서는 제한적 | Offset 기반 Replay 용이 |
| 실패 처리 | ACK/NACK, DLQ, TTL 등 강력 | Consumer 측 처리 전략 필요 |
| 작업 분산 | Consumer 단위 | Partition 단위 |
| 이벤트 보존 | Queue 처리 완료 후 제거 | Retention Policy |
| 대표 용도 | 비동기 작업, 서비스 간 메시징 | 이벤트 스트리밍, 로그, 데이터 파이프라인 |
10. 언제 RabbitMQ를 사용할까?
다음과 같은 상황에서는 RabbitMQ가 잘 맞는다.
"이 작업을 누군가 반드시 처리해야 한다."
예를 들어
- 주문 생성 후 알림 발송
- 이메일 발송
- 결제 후 후속 처리
- 비동기 Background Job
- 서비스 간 Command 전달
- 실패 메시지 Retry / DLQ 처리
등이다.
특히 메시지별 ACK, Retry, TTL, Priority, Dead Letter 처리 등이 중요하다면 RabbitMQ의 Queue 모델이 자연스럽다.
11. 언제 Kafka를 사용할까?
다음과 같은 상황에서는 Kafka가 잘 맞는다.
"이 이벤트를 기록해 두고 여러 시스템에서 활용해야 한다."
예를 들어
- 사용자 행동 로그
- 주문 이벤트 스트림
- 대규모 로그 수집
- 실시간 데이터 파이프라인
- CDC(Change Data Capture)
- 이벤트 소싱
- 실시간 분석
- 장기간 이벤트 Replay
등이다.
특히 하나의 이벤트를 여러 Consumer가 독립적으로 읽거나 과거 이벤트를 다시 처리해야 한다면 Kafka의 Log 구조가 강점을 가진다.
12. 결국 무엇을 선택해야 할까?
단순히
"Kafka가 처리량이 높으니까 Kafka"
또는
"MSA에서는 RabbitMQ"
처럼 선택하면 안 된다.
먼저 메시지의 성격을 봐야 한다.
작업 자체가 중요하다면
주문 생성
↓
재고 차감
↓
알림 전송
각 작업이 정상적으로 처리되었는지 관리하고 실패한 작업을 개별적으로 재시도해야 한다.
→ RabbitMQ
이벤트 기록 자체가 중요하다면
OrderCreated
↓
Kafka Topic
├─ Analytics
├─ Recommendation
├─ Monitoring
└─ Data Warehouse
여러 Consumer가 독립적으로 같은 이벤트를 사용하고 필요하면 과거 이벤트도 다시 처리해야 한다.
→ Kafka
결국 가장 핵심적인 질문은 이것이다.
"나는 메시지를 전달하고 처리하고 싶은가, 아니면 이벤트를 기록하고 다시 읽고 싶은가?"
이 질문에서 출발하면 RabbitMQ와 Kafka의 선택 기준이 훨씬 명확해진다.
13. 한 줄 정리
RabbitMQ
메시지를 적절한 Consumer에게 전달하고, 해당 작업이 제대로 처리되도록 관리하는 데 강점이 있는 메시지 브로커
Kafka
이벤트를 분산 로그에 지속적으로 기록하고 여러 Consumer가 독립적으로 읽고 재처리할 수 있도록 하는 이벤트 스트리밍 플랫폼
최근에는 RabbitMQ Stream과 Kafka의 Queue Semantic 등으로 두 기술의 기능 영역이 점점 겹치고 있다.
따라서 단순히 Queue vs Stream으로 구분하기보다는 메시지 전달·작업 처리와 이벤트 저장·재처리 중 어떤 요구사항이 시스템의 중심인지를 기준으로 선택하는 것이 중요하다.
'CS & Algorithm > CS' 카테고리의 다른 글
| [CS] CPU 스케줄링과 TCP/UDP 차이 (0) | 2026.09.03 |
|---|---|
| [CS] GC와 Spring MVC 요청 처리 과정 (0) | 2026.09.03 |
| [CS] DB JOIN과 이진 탐색 (0) | 2026.08.30 |
| [Plus] Let’s Encrypt 인증서를 적용하면 HTTPS는 어떻게 동작할까? (0) | 2026.08.30 |
| [CS] 가상 메모리와 HTTP vs. HTTPS (0) | 2026.08.30 |