메시징 시스템과 Kafka의 차이점
전통적인 메시징 시스템
메시지 큐 (Message Queue)
대표적인 시스템: RabbitMQ, ActiveMQ, Amazon SQS
특징:
Producer → Queue → Consumer
- Point-to-Point 모델
- 메시지가 한 번 소비되면 큐에서 삭제됨
- Consumer가 메시지를 가져가면(pull) 다른 Consumer는 받을 수 없음
사용 사례:
- 작업 분배 (Task Distribution)
- 비동기 처리 (Async Processing)
Pub/Sub 시스템 (Publish/Subscribe)
대표적인 시스템: Redis Pub/Sub, Google Pub/Sub
특징:
Publisher → Topic → [Subscriber1, Subscriber2, Subscriber3]
- 여러 구독자가 동일한 메시지를 받을 수 있음
- 메시지는 일반적으로 메모리에만 저장
- 구독자가 없으면 메시지 손실
사용 사례:
- 실시간 알림
- 브로드캐스팅
Kafka의 차별점
Kafka는 전통적인 메시징 시스템의 장점을 결합하고 확장한 시스템입니다.
1. 메시지 영속성 (Persistence)
전통적인 메시징 시스템
메시지 생성 → 메모리 저장 → 소비 → 삭제
- 소비되면 메시지 삭제
- 재처리 불가능
Kafka
메시지 생성 → 디스크 저장 → 소비 → 보관 (설정된 기간)
- 메시지가 소비되어도 삭제되지 않음
- 설정한 보관 기간(retention period) 동안 유지
- 동일한 메시지를 여러 번 재처리 가능
예시:
# 7일간 보관
retention.ms=604800000
# 10GB까지 보관
retention.bytes=107374182402. 메시지 소비 모델
전통적인 메시징 시스템 (Push 모델)
Queue → [메시지 푸시] → Consumer
- 시스템이 Consumer에게 메시지를 푸시
- Consumer의 처리 속도 고려 필요
- Backpressure 관리 복잡
Kafka (Pull 모델)
Consumer → [메시지 요청] → Kafka → [메시지 응답] → Consumer
- Consumer가 자신의 속도에 맞춰 메시지를 가져감 (pull)
- Consumer가 처리 속도 제어
- 필요시 배치 처리 가능
3. 확장성 (Scalability)
전통적인 메시징 시스템
- 주로 수직 확장 (Vertical Scaling)
- 클러스터링 지원이 제한적
- 처리량 한계 존재
Kafka
- 수평 확장 (Horizontal Scaling)
- Partition을 통한 병렬 처리
- Broker 추가로 무한 확장 가능
Topic: orders
├── Partition 0 → Broker 1
├── Partition 1 → Broker 2
├── Partition 2 → Broker 3
└── Partition 3 → Broker 4
4. Consumer Group
전통적인 메시징 시스템
- 큐: 여러 Consumer가 메시지를 나눠 받음 (경쟁)
- Pub/Sub: 모든 Subscriber가 모든 메시지를 받음
Kafka
Topic: user-events
├── Consumer Group A (실시간 분석)
│ ├── Consumer 1 → Partition 0, 1
│ └── Consumer 2 → Partition 2, 3
│
└── Consumer Group B (데이터 저장)
├── Consumer 1 → Partition 0
├── Consumer 2 → Partition 1
├── Consumer 3 → Partition 2
└── Consumer 4 → Partition 3
- 동일한 Consumer Group 내에서는 메시지 분산 (큐 모델)
- 다른 Consumer Group은 모든 메시지 수신 (Pub/Sub 모델)
- 두 모델의 장점을 모두 활용
5. 순서 보장 (Ordering)
전통적인 메시징 시스템
- 전역 순서 보장이 어려움
- 병렬 처리 시 순서 보장 불가
Kafka
- Partition 단위로 순서 보장
- 동일한 Key를 가진 메시지는 같은 Partition에 저장
- Partition 내에서는 엄격한 순서 유지
User A의 이벤트 → Partition 0 → [순서 보장]
User B의 이벤트 → Partition 1 → [순서 보장]
User C의 이벤트 → Partition 2 → [순서 보장]
6. 처리량 (Throughput)
| 시스템 | 일반적인 처리량 |
|---|---|
| RabbitMQ | ~20,000 msg/sec |
| ActiveMQ | ~10,000 msg/sec |
| Kafka | ~1,000,000+ msg/sec |
Kafka가 높은 처리량을 달성하는 이유:
- 순차적 디스크 I/O (Sequential Disk I/O)
- Zero Copy 기술
- Batch Processing
- Compression
7. 데이터 재처리 (Replay)
전통적인 메시징 시스템
메시지 소비 → 삭제 → 재처리 불가능
Kafka
메시지 소비 → 보관 유지 → Offset 조정으로 재처리 가능
예시 시나리오:
1. 오늘 00:00부터 데이터 처리
2. 10:00에 버그 발견
3. 버그 수정 후 00:00 Offset으로 되돌아가서 재처리
# Offset을 특정 시점으로 재설정
kafka-consumer-groups --bootstrap-server localhost:9092 \
--group my-group \
--topic my-topic \
--reset-offsets --to-datetime 2025-01-13T00:00:00.000 \
--execute비교 표
| 특징 | 전통적인 MQ | Kafka |
|---|---|---|
| 메시지 보관 | 소비 후 삭제 | 설정 기간 동안 보관 |
| 소비 모델 | Push | Pull |
| 재처리 | 불가능 | 가능 (Offset 조정) |
| 확장성 | 제한적 | 높음 (수평 확장) |
| 처리량 | 보통 | 매우 높음 |
| 순서 보장 | 제한적 | Partition 단위 보장 |
| 지연시간 | 낮음 (수 ms) | 보통 (수십 ms) |
| 사용 목적 | 메시지 전달 | 이벤트 스트리밍 |
언제 무엇을 사용할까?
전통적인 메시징 시스템 (RabbitMQ 등)을 선택하는 경우:
- 낮은 지연시간이 중요한 경우
- 메시지가 복잡한 라우팅 규칙이 필요한 경우
- 작은 규모의 메시지 전달
- 우선순위 큐가 필요한 경우
Kafka를 선택하는 경우:
- 대용량 데이터 처리가 필요한 경우
- 이벤트를 여러 시스템에서 재사용해야 하는 경우
- 데이터 재처리가 필요한 경우
- 높은 처리량이 중요한 경우
- 실시간 스트림 처리가 필요한 경우
- 로그 수집, 이벤트 소싱, CDC(Change Data Capture) 등
실제 사용 예시
RabbitMQ 적합한 사례
주문 시스템 → RabbitMQ → [결제 서비스, 재고 서비스, 알림 서비스]
- 낮은 지연시간으로 즉시 처리
- 메시지 한 번 처리 후 완료
Kafka 적합한 사례
클릭 이벤트 → Kafka → [실시간 분석, 추천 엔진, 데이터 레이크, 감사 로그]
- 대용량 데이터
- 여러 시스템에서 동일 이벤트 소비
- 나중에 재분석 가능
다음 단계
- Kafka의 주요 특징과 장점
- Kafka 사용 사례
- Topic과 Partition - Kafka의 핵심 아키텍처
댓글 (0)