[기술 스터디] Kafka vs RabbitMQ vs RocketMQ vs Pulsar: 4대 메시지 미들웨어 완벽 비교
최근 메시지 미들웨어(Message Middleware)를 깊이 있게 스터디하면서, 업계의 4대장이라 불리는 Kafka, RabbitMQ, RocketMQ, 그리고 Pulsar 를 비교 분석해보았습니다.
과연 이들은 서로 어떤 차이점이 있을까요? 오늘은 제가 탐구한 결과를 바탕으로 아키텍처 설계, 성능, 확장성, 신뢰성이라는 4가지 관점에서 상세히 비교해보고자 합니다. 학습한 내용을 정리한 것이니, 혹시 부족하거나 수정이 필요한 부분이 있다면 언제든 피드백 부탁드립니다.
아키텍처 설계
Kafka (카프카)
Kafka의 정체성은 '분산 로그'입니다. Producer가 메시지를 보내면 Broker는 이를 파티션 로그(Partition Log)에 순차적으로 기록합니다. Consumer는 이 로그에서 데이터를 직접 가져가는(Pull) 구조죠. 클러스터 관리는 ZooKeeper가 담당합니다. (최근 버전은 Kraft 모드로 ZK를 걷어내는 추세지만, 기본 구조는 이렇습니다.)

RabbitMQ (래빗엠큐)
RabbitMQ는 AMQP(Advanced Message Queuing Protocol) 프로토콜을 기반으로 합니다. 프로듀서가 메시지를 익스체인지(Exchange)로 보내면, 익스체인지는 설정된 라우팅 규칙에 따라 메시지를 여러 큐(Queue)에 전달하고, 최종적으로 컨슈머가 이 메시지를 소비합니다. Direct, Topic, Fanout, Headers 등 다양한 라우팅 모델을 제공하여 복잡한 메시지 흐름을 처리하는 데 매우 유연합니다.

RocketMQ (로켓엠큐)
RocketMQ는 경량화된 네임서버(NameServer)와 브로커(Broker) 아키텍처를 채택했습니다. 프로듀서는 네임서버에서 라우팅 정보를 얻은 후, 브로커의 메시지 큐(MessageQueue)에 메시지를 씁니다. 트랜잭션 메시지와 순서 보장 메시지를 지원하는 것이 특징입니다.

Pulsar (펄사)
Pulsar는 브로커(Broker)와 북키퍼(BookKeeper, 스토리지 계층) 아키텍처를 사용하여 컴퓨팅과 스토리지를 분리했습니다. 이러한 구조 덕분에 계층형 스토리지(Tiered Storage)를 지원하며, 태생적으로 클라우드 네이티브 환경에 최적화되어 있습니다.

성능
지표 | Kafka | RabbitMQ | RocketMQ | Pulsar |
처리량 (Throughput) | 단일 노드 수십만~백만 TPS, 클러스터 확장 시 백만 TPS 이상 | 단일 노드 약 수만 TPS, 동시성 높을 때 성능 저하 | 단일 노드 수십만 TPS, 클러스터 확장 시 백만 단위 | 단일 노드 수십만 TPS, 대규모 클러스터에서 백만 이상 |
메시지 지연 시간 (Latency) | 보통 수십 밀리초(ms) | 밀리초(ms) 단위, 처리량 높을 때 지연 시간 증가 | 보통 수십 밀리초(ms) | 보통 수십 밀리초(ms) |
메시지 적재 능력 | 대규모 적재 및 과거 데이터 재생(Replay) 에 강함 (디스크 기반, 파티션 로그) | 장기간, 대규모 적재에 부적합, 메모리 부담 큼 | 장기간 적재 지원 | BookKeeper 기반, 다중 복제로 대규모 적재 및 계층형 스토리지 지원 |
참고: 위 데이터는 참고용이며, 정확한 벤치마크는 각 제품의 공식 문서를 확인하시기 바랍니다.
확장성
Kafka: 파티션(Partition) 을 통해 수평적으로 확장합니다. 하나의 토픽(Topic)을 여러 파티션으로 나누어 병렬 처리가 가능합니다. 브로커 클러스터는 수백, 수천 개의 노드로 확장할 수 있어 대규모 실시간 데이터 스트림을 효과적으로 지원합니다.
RabbitMQ: 다중 노드 클러스터 모드로 확장하지만, 큐(Queue)를 여러 노드에 복제해야 하므로 동기화 비용이 높습니다. 이 때문에 중규모 데이터 환경에 더 적합합니다.
RocketMQ: 브로커와 큐의 수를 늘려 성능을 향상시킵니다. 스토리지 계층에서 동적으로 브로커를 추가할 수 있고, 컨슈머 또한 독립적으로 확장 가능하여 무중단 확장이 가능합니다. 대규모 분산 시스템 환경에서 비교적 친화적인 확장 방식을 제공합니다.
Pulsar: 컴퓨팅-스토리지 분리 구조 덕분에, 처리 능력을 높이려면 브로커만, 저장 용량을 늘리려면 북키퍼만 독립적으로 확장할 수 있습니다. 여기에 멀티테넌시(Multi-tenancy)와 동적 자원 할당 기능까지 더해져 대규모 클라우드 네이티브 환경에 가장 이상적입니다.
안정성 (신뢰성)
Kafka: 파티션 다중 복제(Multi-replica) 메커니즘으로 데이터 안정성을 보장합니다. 기본적으로 At-least-once(최소 한 번 전송) 시맨틱을 제공하며, 멱등성(Idempotent) 쓰기와 트랜잭션 기능을 통해 Exactly-once(정확히 한 번 전송) 를 구현할 수 있습니다.
RabbitMQ: 3.8.0 버전부터 Raft 합의 알고리즘 기반의 쿼럼 큐(Quorum Queue) 를 도입하여 안정성을 크게 향상시켰습니다. At-least-once를 보장하여 메시지 유실은 없지만, 중복이 발생할 수 있으므로 클라이언트 측에서 멱등성 처리가 필요합니다.
RocketMQ: 마스터-슬레이브 복제(Master-Slave Replication)와 디스크 동기화로 신뢰성을 확보합니다. 최신 버전의 DLedger는 Raft 프로토콜을 기반으로 하여 자동 장애 복구(Failover)를 지원하므로 내결함성이 한층 강화되었습니다.
Pulsar: BookKeeper의 다중 복제 스토리지 덕분에 브로커에 장애가 발생해도 데이터 안전을 보장합니다. 멀티테넌시와 자원 격리를 기본적으로 지원하여 안정성과 내결함성이 뛰어나며, 특히 클라우드 네이티브 환경에서 강점을 보입니다.
최종 요약
복잡한 건 싫고 결론만 원하신다면?
Kafka: 로그 수집, 스트리밍, 빅데이터 파이프라인? 닥치고 Kafka.
RabbitMQ: 복잡한 라우팅이 필요하거나, 빠릿빠릿한 응답이 중요한 소/중규모 시스템.
RocketMQ & Pulsar: 금융/결제 등 높은 신뢰성이 필요하거나(Rocket), 클라우드 환경에서 유연한 확장이 필요할 때(Pulsar).
특징 | Kafka | RabbitMQ | RocketMQ | Pulsar |
개발 언어 | Java/Scala | Erlang | Java | Java |
소비 모델 | Pull | Push | Pull | Pull + Push |
처리량 | 매우 높음 | 보통 | 높음 | 높음 |
지연 시간 | 낮음 | 매우 낮지만, 고처리량에서 제한됨 | 낮음 | 낮음 |
메시지 적재 능력 | 매우 강력함 (장기 저장 및 재처리 가능) | 약함 | 강함 | 강함 (계층형 스토리지, 클라우드 네이티브) |
확장성 | 매우 뛰어남 (파티션 기반 확장) | 보통 (클러스터 및 하드웨어 자원에 제약) | 뛰어남 | 매우 뛰어남 (컴퓨팅-스토리지 분리) |
안정성 | 매우 높음 (다중 복제) | 높음 (쿼럼 큐로 안정성 향상) | 높음 (DLedger로 장애 복구 능력 향상) | 매우 높음 (스토리지 분리 + 다중 복제) |
프로토콜 지원 | Kafka 고유 프로토콜 | AMQP, MQTT, STOMP 등 | RocketMQ 고유 및 다중 프로토콜 확장 | Pulsar 고유 및 다중 프로토콜 확장 |
커뮤니티/생태계 | 매우 활발, 가장 강력한 생태계 | 안정적, 풍부한 플러그인 | 아시아권 사용자 다수, 클라우드 지원 우수 | 신흥 주자, 클라우드 네이티브 중심으로 빠르게 성장 |
주요 사용 사례 | 로그 수집, 실시간 데이터 웨어하우스, 데이터 버스 | 실시간 통신, 작업 스케줄링, 요청-응답 패턴 | 이커머스 주문, 금융 거래, 결제 시스템 | SaaS 플랫폼, 멀티 데이터센터 메시지 스트리밍 |