1. 문제 상황
서비스 간 비동기 메시징을 도입하려 할 때, Redis PUB/SUB, RabbitMQ, Kafka 중 어떤 메시지 브로커를 사용할지 고민해야 했다. 각각의 기술은 특정 용도에 강점을 가지고 있지만, 서비스 요구 사항에 따라 적절한 선택이 필요했다.
1.1 서비스 요구 사항
- At-Least-Once 메시지 보장: 메시지가 손실되지 않아야 함
- 구독형 메시징 지원: 하나의 이벤트를 여러 개의 소비자가 구독할 수 있어야 함
- 확장성과 내구성: 대량의 메시지를 안정적으로 처리할 수 있어야 함
- 클러스터링 및 장애 복구 가능성: 서비스가 확장되더라도 안정적으로 운영 가능해야 함
이를 기반으로 Redis PUB/SUB, RabbitMQ, Kafka를 비교한 결과, Kafka를 선택하게 되었다.
2. Redis PUB/SUB의 한계
Redis는 빠르고 간단한 구독(Publish-Subscribe) 모델을 제공하지만, 특정 요구 사항을 충족하기 어려웠다.
2.1 장점
- 빠른 메시징 속도: 메모리 기반이므로 지연이 거의 없음
- 간단한 구조: 설정이 쉽고 사용하기 간편함
- 실시간 처리 가능: 즉각적인 메시지 전송 가능
2.2 한계점
- 메시지 저장 기능 부족: 메시지가 소비되면 사라지므로, 메시지를 다시 받아야 할 경우 별도의 저장소가 필요함
- 신뢰성 부족: 서버가 재시작되면 메시지 손실 가능성 높음
- 확장성 부족: 클러스터링을 통한 메시지 분산이 어렵고, 트래픽이 커질수록 관리 부담 증가
Redis를 사용하면서 At-Least-Once 보장을 하려면 별도의 저장소(RDBMS, 파일 시스템 등)에 데이터를 보관해야 함
3. RabbitMQ의 한계
RabbitMQ는 전통적인 메시지 브로커로서 신뢰성 높은 메시징을 제공하지만, 특정 요구 사항을 만족하기 어려웠다.
3.1 장점
- 메시지 저장 가능: 디스크 기반으로 메시지를 보관 가능
- 복잡한 메시지 라우팅 지원: 여러 개의 Exchange 타입을 제공하여 유연한 메시지 전달 가능
- 트랜잭션 지원: 메시지를 처리하는 동안 실패하면 다시 처리 가능
3.2 한계점
- 구독형 메시징 부족: 하나의 메시지를 여러 개의 그룹이 구독하는 기능이 없음 (여러 그룹에서 동일한 메시지를 사용하려면 별도의 메시지 복제 필요)
- 확장성 문제: 클러스터링을 통해 확장 가능하지만, 대량 트래픽 처리에는 한계
- 메시지 처리량이 Kafka보다 낮음: 대량의 데이터 스트리밍에는 적합하지 않음
RabbitMQ는 메시지 저장과 트랜잭션을 보장하지만, 하나의 메시지를 여러 개의 소비자가 구독하는 구조가 필요할 경우 메시지를 여러 번 전송해야 함.
4. Kafka를 선택한 이유
Kafka는 대량의 메시지를 안정적으로 처리할 수 있는 분산형 메시지 브로커로, 높은 내구성과 확장성을 제공한다.
4.1 장점
- 메시지 저장 가능: 메시지를 로그 형태로 저장하여 재처리 가능
- 구독형 메시징 지원: 하나의 메시지를 여러 개의 컨슈머 그룹이 구독 가능
- 확장성 우수: 클러스터링을 통해 수평 확장 가능
- 대량 데이터 처리 가능: 초당 수백만 개의 메시지를 처리할 수 있음
- 장애 복구 가능: 데이터 복제(replication) 기능이 있어 장애 발생 시에도 데이터 유실 없음
4.2 한계점
- 구성 및 운영이 복잡: Kafka 클러스터를 관리하려면 추가적인 인프라 설정이 필요함
- 레이지 소비(Lazy Consumption) 특성: 실시간 처리보다는 대량의 데이터를 안정적으로 전달하는 데 적합
- AWS에서 비용 부담: Kafka를 AWS에서 운영할 경우 클러스터링 비용이 상당히 높음
최종 선택: Kafka는 대량의 메시지를 안정적으로 처리해야 하고, 여러 개의 서비스가 동일한 메시지를 구독해야 하는 경우 최적의 선택이었다. 특히 메시지가 일정 시간 보관된다는 점에서 MSA의 정합성 문제 해결에 큰 장점을 보였다.
5. Kafka 사용 결정 요약
메시지 브로커 |
구독형 메시징 |
메시지 저장 |
확장성 |
운영 비용 |
Redis PUB/SUB |
O |
X |
제한적 |
낮음 |
RabbitMQ |
X |
O |
중간 |
중간 |
Kafka |
O |
O |
높음 |
높음 |
5.1 Kafka를 선택한 이유
- At-Least-Once 메시지 보장이 가능하고, 메시지를 저장할 수 있음
- 여러 컨슈머 그룹이 동일한 메시지를 구독할 수 있어 중복 메시지 전송이 필요 없음
- 대량 트래픽을 안정적으로 처리할 수 있는 확장성 제공
5.2 추가 고려사항
- Kafka를 AWS에서 클러스터링으로 운영할 경우 비용이 높아질 수 있음
- 작은 규모의 서비스에서는 Kafka 대신 RabbitMQ나 Redis를 사용하여 운영 부담을 줄일 수도 있음
결과적으로, Kafka는 대규모 분산 시스템에서 높은 확장성과 데이터 보존 기능이 필요한 경우 최적의 선택지였으며, 서비스의 요구 사항에 맞춰 RabbitMQ나 Redis와 병행하여 사용할 수도 있다.
더보기
Kafka가 RabbitMQ나 Redis Pub/Sub보다 빠르고 대용량 처리에 적합한 이유는 설계 철학과 내부 아키텍처에서 차이가 납니다.
아래에 핵심 비교와 함께 Kafka가 왜 "빠르고 튼튼한 메시지 처리 시스템"인지 깔끔하게 정리해드릴게요.
🚀 Kafka가 더 빠른 이유 요약
항목 Kafka RabbitMQ Redis Pub/Sub
기반 구조 |
디스크 기반 로그 (Append-only) |
메모리 기반 + 디스크 저장 (옵션) |
순수 메모리 기반 |
처리 방식 |
Batch 전송, Zero-Copy, 비동기 전송 |
메시지 큐잉 후 소비자에게 푸시 |
Pub/Sub으로 단순 브로드캐스트 |
확장성 |
파티션 기반 수평 확장 (분산 처리) |
큐 기반, 확장은 가능하나 상대적으로 어려움 |
클러스터링 가능하지만 분산 처리 설계 아님 |
내구성 |
디스크에 저장, 메시지 유실 없음 |
디스크 저장 설정 가능 |
기본적으로 휘발성, 메시지 유실 가능 |
처리량 (Throughput) |
초당 수십~수백만 메시지 처리 가능 |
중간 수준 (적절한 구성 필요) |
작고 빠르지만 지속성과 확장성 부족 |
메시지 소비 방식 |
Pull 기반, 컨슈머가 원하는 속도로 읽음 |
Push 기반, 소비자가 느리면 큐 적재됨 |
브로드캐스트 기반, 메시지 저장 안 됨 |
🔍 주요 기술적 차이 (좀 더 디테일하게)
✅ Kafka: 왜 빠른가?
- 디스크 기반 Append-Only 구조
→ 데이터는 순차적으로만 기록되며, 랜덤 I/O보다 훨씬 빠름.
→ 디스크를 효율적으로 사용하므로 수백 GB 이상 데이터도 OK.
- Zero-Copy 기술 사용
→ 메시지를 전송할 때, OS 커널 버퍼를 직접 활용해서 CPU 사용 없이 네트워크 전송.
→ Kafka가 초고속인 핵심 기술 중 하나.
- 배치 처리 + 압축 전송
→ 여러 메시지를 묶어서 한번에 전송, 압축으로 네트워크 사용 최적화.
- 분산 구조 (Partition + Broker)
→ 토픽을 여러 파티션으로 나눠 병렬 처리 → 무한 확장 가능.
❗ RabbitMQ와 Redis는 왜 느릴 수 있을까?
🐰 RabbitMQ
- AMQP 기반으로 메시징 규약이 더 정교하지만, 무겁고 유연함이 있음.
- Push 기반이라 소비자가 느리면 큐에 메시지가 쌓이고 병목 발생.
- 메시지 보존, 라우팅, 보안 설정 등은 다양하지만, 고속 처리보다는 안정적 메시징에 초점.
🧠 Redis Pub/Sub
- 단순한 메모리 기반 브로드캐스트 방식.
- 메시지를 publish할 때 구독 중인 클라이언트에게 바로 전달.
- 저장하지 않기 때문에 유실 위험 높고, 스케일링 어려움.
- 초고속이긴 하지만 신뢰성과 유연성이 낮음, 실시간 로그나 임시 알림 등에 적합.
🎯 언제 Kafka를 쓰면 좋은가?
- 수십만 건 이상 데이터를 실시간으로 안정적이고 빠르게 처리하고 싶을 때
- 로그 수집, 스트리밍, 빅데이터 파이프라인, 이벤트 중심 아키텍처 등
- 시스템 간 비동기 연동 + 메시지 유실 방지가 중요한 경우
💡 요약 정리 한 줄씩!
- Kafka: 빅데이터용 초고속 트럭 (순차적, 대용량, 튼튼함)
- RabbitMQ: 스마트한 우편집중국 (메시지 라우팅, 신중한 전달)
- Redis Pub/Sub: 무전기 (빠르지만 저장 안 되고, 즉시 전달만)