Architecture

어떤 메시지 큐를 선택할까? (Kafka · RabbitMQ · Redis)

누구세연 2025. 12. 17. 22:00

최근에 비동기 처리를 추가할 일이 생겼는데, 막상 시작하려니
“그래서 나는 어떤 큐를 써야 하지?”라는 고민이 제일 먼저 들었습니다.
 
Kafka도 흔히 큐처럼 사용되고, RabbitMQ는 이름부터 Message Queue이고, Redis로도 큐를 만들어 쓸 수 있다 보니 더 헷갈리더라고요.
정리해 보니 결국 중요한 건 이름이 아니라, 내가 원하는 동작이었습니다.
메시지를 다시 처리해야 하는지, 작업을 어떻게 나눌 건지, 유실을 어디까지 허용할 수 있는지, 운영 복잡도는 감당 가능한지 같은 부분이 중요했습니다.
그래서 이 글에서는 먼저 선택해 보고(선택표) → 기준을 세운 뒤(질문) → 각 큐를 이해하는(설명) 순서로 정리해보려 합니다.
 
 


 

먼저 선택표부터

상황/요구추천
이벤트 로그, CDC, 재처리·재생 가능해야 함Kafka
작업 큐, 라우팅/재시도/DLQ가 필요함RabbitMQ (혹은 SQS/ActiveMQ)
초경량 비동기, 매우 낮은 지연, 이미 Redis 보유Redis Queue/Streams
기록용 + 즉시 처리 병행Kafka로 기록, Redis로 즉시 작업

 
여기서 끝내도 되고, “왜?”가 궁금하면 아래 “4가지 질문”으로 한 번 더 체크해 보면 좋습니다.

 

선택을 결정짓는 4가지 질문

표가 애매하게 느껴지는 경우에는 이 질문 4개만 답해보면 방향이 잡힙니다.

  • 메시지를 다시 읽어야 하나? (과거 재생, 리플레이)
  • 여러 Consumer가 각각 처리해야 하나? 아니면 하나만 처리하면 되나?
  • 장애 시 유실을 허용할 수 있는가?
  • 운영 복잡도(클러스터, 모니터링, 튜닝)를 감당할 수 있는가?

 

용어만 정리..!

• Producer: 메시지를 생성해 큐/토픽으로 보내는 주체.  
• Consumer: 메시지를 받아 실제 작업을 수행하는 주체.  
• Queue/Topic: 메시지가 소비되기 전까지 머무는 논리적 단위.  
  Kafka는 Topic이라는 로그 구조를 사용하고, RabbitMQ와 Redis는 Queue나 Stream/List 같은 구조로 메시지를 분배한다.  
• Offset/Ack: 메시지 처리 진행 상황을 표시하는 방식.  
  Kafka는 Offset으로 읽은 위치를 기록하고, RabbitMQ/Redis Streams는 Ack를 통해 처리 완료를 확정한다.

 


 
 

큐별로 뭐가 다를까?

이제부터는 Kafka/RabbitMQ/Redis가 각각 어떤 상황에 강한지, “쓰임새 기준”으로 정리해 보겠습니다.

Kafka (이벤트 스트리밍)

  • 한마디로: 이벤트를 길게 쌓아두고, 필요하면 과거까지 되감아 보는 로그 창고.
  • 디스크 기반 로그, Offset으로 재처리·재생 가능.
  • 매우 높은 처리량, 다수 Consumer가 각자 읽어감.
  • 운영 난이도 높음(클러스터/모니터링/스키마 관리 필요).
  • 주 용도: 도메인 이벤트, CDC, 로그 파이프라인.

Kafka 아키텍처 개요

  • Producer가 메시지를 Topic/Partition에 push(실제로는 브로커에 append)합니다.
  • 다수의 Broker가 Topic을 Partition 단위로 분산 저장해 확장성과 내결함성을 확보합니다.
  • Consumer가 pull 방식으로 읽으며, Consumer Group을 사용해 스케일아웃합니다.

Topic/Partition/Consumer Group 동작

  • 하나의 Topic은 여러 Partition으로 나뉘어 병렬 처리·저장이 가능합니다.
  • Producer는 특정 Partition에 레코드를 보냅니다(키 기반 파티셔닝 등).
  • Consumer Group은 Partition을 나눠 맡아 읽고, 그룹 내에서 메시지가 중복 처리되지 않도록 조정합니다.

Offset으로 재생·재처리

  • 각 Partition은 순차적인 Offset을 갖습니다. Consumer Group은 자신이 어디까지 읽었는지 Offset으로 기록합니다.
  • Offset을 되돌리면 과거 메시지를 다시 읽어 재처리·재생이 가능합니다.
  • 로그가 디스크에 일정 기간 보관되므로, 재처리/분석/장애 복구 시 유용합니다.

 

RabbitMQ (메시지 브로커)

  • 한마디로: 작업 분배기. 들어온 일을 큐에 넣고 여러 작업자가 나눠 처리.
  • 메시지를 큐에 넣고 한 Consumer가 처리(워크 큐 모델).
  • Exchange/Binding으로 라우팅 유연, Ack/Retry/DLQ 기본 제공.
  • 처리량·운영 복잡도 중간, 작업 큐에 최적.
  • 주 용도: 주문 처리, 백그라운드 잡, 워크플로 분기.

RabbitMQ 라우팅 개요

  • Publisher가 메시지를 Exchange에 발행하면, Binding 규칙에 따라 하나 혹은 여러 Queue로 복사·분기됩니다(Direct/Topic/Fanout/Headers).
  • 각 Queue는 소비자에게 분배되며, 소비자는 Ack로 처리 완료를 알립니다. Ack가 없으면 재전송되거나 DLQ로 보낼 수 있습니다.
  • “한 메시지 = 한 작업” 모델에 강해 주문·티켓 처리 같은 워크 큐, 라우팅이 많은 워크플로에 적합합니다.

Redis Queue/Streams (인메모리 큐)

  • 한마디로: 가벼운 전달자. 메모리에 잠깐 올려두고 바로 소비.
  • In-memory라 매우 빠름, 설정·운영이 단순.
  • 기본 List/PubSub/Streams로 큐 구현. Streams는 Consumer Group/Offset 지원.
  • 내구성·장기 보관은 약함, 재처리·Retry 로직은 직접 설계 필요.
  • 주 용도: 알림 트리거, 캐시 갱신, 단기·경량 백그라운드 작업.

Redis Streams: Consumer Group 처리

  • Producer가 XADD로 스트림에 메시지를 append합니다(시간순 로그).
  • Consumer Group이 XREADGROUP으로 메시지를 가져가고, 처리 후 XACK으로 완료를 알립니다.
  • 각 메시지는 그룹 내에서 한 번만 할당되며, Ack 되지 않은 메시지는 Pending List에 남아 재전달이 가능합니다.
  • 여러 Consumer 인스턴스가 병렬로 처리하되, 같은 메시지가 중복 소비되지 않게 조정되는 점이 핵심입니다.

Redis Pub/Sub: 실시간 브로드캐스트

  • Publisher가 채널에 메시지를 Publish 하면, 구독 중인 Subscriber가 곧바로 수신합니다.
  • 메시지가 Redis에 남지 않으므로 Subscriber가 없거나 잠시 끊겨 있으면 유실됩니다.
  • “실시간 알림”처럼 즉시 전달이 중요하고 유실이 치명적이지 않은 경우에 적합합니다.

Redis List Queue: 단순 FIFO

  • LPUSH로 넣고 RPOP 또는 BLPOP으로 빼는 단순 FIFO 큐입니다.
  • 별도 Ack 개념이 없어 소비자가 실패하면 재처리를 직접 구현해야 합니다.
  • 간단한 백그라운드 작업이나 일시적 큐잉에 적합하지만, 안정적 재처리나 DLQ가 필요하면 Streams나 별도 로직이 필요합니다.

 


 
 

큐별 동작 원리 요약

위 내용을 “동작 방식” 기준으로 한 번에 요약하면 이렇게 정리됩니다.

  • Kafka: Producer가 Topic/Partition에 로그를 append(디스크). Consumer Group이 Offset을 기준으로 읽고 commit 합니다. 메시지는 보관 기간 동안 남아 여러 Consumer가 각자 읽을 수 있고, 과거 재생도 가능합니다.
  • RabbitMQ: Producer → Exchange → Binding 규칙으로 Queue에 라우팅. Consumer가 메시지를 받아 Ack 하며, Ack가 없으면 재전송(DLQ로 이동 가능)됩니다. 1개 큐의 메시지를 여러 Consumer가 “나눠 처리”하는 워크 큐에 강점이 있습니다.
  • Redis Queue/Streams: List는 LPUSH/RPOP의 단순 FIFO(ack 없음). Pub/Sub은 저장 없이 즉시 전달(수신자가 없으면 유실). Streams는 append-only 로그 + Consumer Group/Offset으로 기본 ack/재전송을 지원해 Redis 내에서 가장 브로커스러운 모델입니다.

 


 

패턴별 추천

  • 로그/이벤트 파이프라인: Kafka (재생·다중 소비 필요).
  • 업무/배치 작업 큐: RabbitMQ/SQS (Ack/Retry/DLQ, 라우팅 필요).
  • 알림/캐시/짧은 잡: Redis Queue/Streams (지연 최소, 단순 운영).
  • 기록 + 즉시 처리 분리: Kafka로 기록, Redis로 알림·캐시 등 즉시 처리.

 
 
 
 

메시지 큐를 고를 때 성능 지표부터 보기보다는, 이 메시지가 다시 처리되어야 하는지, 여러 소비자가 각각 처리해야 하는지, 유실을 어디까지 허용할 수 있는지를 먼저 정하는 게 더 중요하다고 느꼈습니다.
그 기준으로 보면 Kafka, RabbitMQ, Redis는 경쟁 관계라기보다 각자 잘 맞는 자리가 분명한 도구들입니다.
저는 이 기준을 세운 뒤로 “어떤 큐를 써야 하지?”라는 고민이 많이 줄었습니다.