홈/인프라/Kafka vs RabbitMQ vs NATS vs Redis Streams 선택 가이드: 6개 질문 판정표
인프라메시지 큐 비교Kafka

Kafka vs RabbitMQ vs NATS vs Redis Streams 선택 가이드: 6개 질문 판정표

Kafka, RabbitMQ, NATS JetStream, Redis Streams를 전달 모델·리플레이·순서 보장·운영 부담으로 비교합니다. 6개 질문 판정표, 보존 용량 계산법(흔한 계산 실수 포함), 첫 주에 볼 운영 지표까지 정리했습니다.

Kafka vs RabbitMQ vs NATS vs Redis Streams 선택 가이드: 6개 질문 판정표
목차
  1. "일단 Kafka"가 늘 정답은 아닌 이유
  2. 네 제품의 전달 모델부터 구분하기
  3. 30초 판정표: 6개 질문
  4. 비용 계산: 가격표보다 먼저 맞출 숫자
  5. 선택 후 첫 주에 확인할 운영 지표
  6. 자주 묻는 질문

"일단 Kafka"가 늘 정답은 아닌 이유

메시지 큐를 고를 때 가장 흔한 실수는 필요한 보장 대신 가장 유명한 제품을 고르는 것이다. 일 100만 메시지는 많아 보이지만 초당 평균 약 11.6건(1,000,000 ÷ 86,400)이다. 이 규모라면 Kafka, RabbitMQ, NATS JetStream, Redis Streams 모두 처리량 자체는 문제가 되지 않는다. 선택을 가르는 것은 전달 모델, 재처리(리플레이), 순서 보장 단위, 운영 부담이다.

이 글은 Kafka Streams + Schema Registry 파이프라인 이전에 던졌어야 할 질문, 즉 "우리에게 무엇이 필요한가"를 판정표로 정리한다.

네 제품의 전달 모델부터 구분하기

항목KafkaRabbitMQNATS (Core / JetStream)Redis Streams
기본 모델파티션된 추가 전용 로그익스체인지 → 큐 라우팅 (스트림 큐도 지원)Core: pub/sub, JetStream: 영속 스트림Redis 자료구조인 추가 전용 로그
읽은 메시지보존 기간 동안 남음 (컨슈머가 오프셋 관리)클래식·쿼럼 큐는 ack 후 삭제, 스트림은 남음Core: 저장 안 함, JetStream: 보존 정책에 따라 남음XTRIM/MAXLEN 등으로 자를 때까지 남음
리플레이오프셋을 되돌려 재처리스트림(3.9+)에서 가능, 일반 큐는 불가JetStream 컨슈머의 시작 위치 지정XRANGE/ID 지정 읽기
순서 보장 단위파티션 내부큐 단위(경쟁 소비자가 여럿이면 처리 순서는 깨질 수 있음, Single Active Consumer로 보완)스트림/주제 단위스트림 단위
전달 보장at-least-once 기본, 멱등 프로듀서·트랜잭션으로 exactly-once 처리 구성publisher confirm + consumer ack로 at-least-onceCore: at-most-once, JetStream: at-least-once, 메시지 ID 중복 제거로 exactly-once 구성컨슈머 그룹 + XACK으로 at-least-once
팬아웃컨슈머 그룹마다 전체를 독립적으로 읽음fanout/topic 익스체인지로 큐마다 복사구독자마다 수신, JetStream은 컨슈머별컨슈머 그룹마다 독립 읽기
고가용성복제 계수(보통 3), KRaft 컨트롤러쿼럼 큐(Raft)JetStream 클러스터 복제(R1/R3/R5)Redis 복제/클러스터 (비동기 복제)

몇 가지는 최근 버전에서 바뀌었으니 오래된 글을 그대로 믿지 말자.

  • Kafka 4.0(2025년 3월)부터 ZooKeeper 모드가 제거되어 KRaft만 지원한다. "Kafka = ZooKeeper 클러스터까지 운영"은 더 이상 사실이 아니다.
  • RabbitMQ 4.0에서 클래식 큐 미러링이 제거되었다. 복제가 필요하면 쿼럼 큐나 스트림을 쓴다.
  • Kafka 3.0부터 프로듀서는 기본으로 enable.idempotence=true, acks=all이다(충돌하는 설정이 없을 때).
  • NATS JetStream의 중복 제거는 Nats-Msg-Id 헤더와 스트림의 duplicate window(기본 2분)로 동작한다.
  • Redis Streams에서 ack되지 않은 메시지는 PEL(pending entries list)에 남는다. 죽은 컨슈머의 메시지는 XPENDING으로 찾고 XAUTOCLAIM(6.2+)으로 넘겨받는다.

30초 판정표: 6개 질문

  1. 과거 메시지를 다시 읽어 재처리해야 하는가? (새 서비스가 지난 7일치를 처음부터 소비 등)
  2. 순서가 필요하다면 어느 단위인가? 전역 / 키(주문 ID 등) / 큐
  3. 소비 후 메시지가 사라져야 하는 작업 큐인가, 여러 팀이 같은 이벤트를 각자 읽는 이벤트 로그인가?
  4. 라우팅 규칙이 복잡한가? (헤더·패턴별 분기, 우선순위, 지연 재시도, DLQ)
  5. 유실이 0이어야 하는가? 그렇다면 브로커 복제 + 프로듀서 확인 + 컨슈머 ack가 모두 필요하다
  6. 이 시스템을 맡을 사람이 있는가? 업그레이드, 디스크, 리밸런스, 모니터링을 누가 보나
상황1순위 후보이유주의할 점
여러 소비자가 같은 이벤트를 독립적으로 읽고, 재처리·장기 보존이 핵심Kafka로그 + 컨슈머 그룹 + 오프셋 리셋이 기본 기능, 생태계(Connect, Streams, Schema Registry)파티션 수와 키 설계가 순서·확장성을 결정. 파티션 수는 늘릴 수 있지만 키→파티션 매핑이 바뀐다
작업 큐, 재시도·DLQ·우선순위·복잡한 라우팅RabbitMQ익스체인지·바인딩·DLX·TTL이 기본 기능, 메시지 단위 ack무제한 백로그 저장소로 쓰지 말 것. 복제는 쿼럼 큐로
가벼운 서비스 간 메시징, 요청-응답, 엣지/IoT, 운영 인력이 적음NATS (+JetStream)단일 바이너리, 낮은 운영 부담, 필요할 때만 JetStream 영속성Core NATS는 구독자가 없으면 메시지가 사라진다. 영속이 필요하면 JetStream 스트림을 명시적으로 만든다
이미 Redis를 운영 중이고 소규모 비동기 작업Redis Streams추가 인프라 없음, 컨슈머 그룹 지원메모리에 저장되므로 보존량이 곧 메모리 비용. 비동기 복제라 장애 조치 시 최근 쓰기를 잃을 수 있다

비용 계산: 가격표보다 먼저 맞출 숫자

클라우드 단가는 리전과 시점에 따라 바뀌므로 이 글에서는 고정 금액을 쓰지 않는다. 대신 어떤 제품이든 같은 방식으로 견적을 내도록 입력값을 맞추자. 예시는 일 100만 메시지 × 평균 2KB × 보존 7일이다.

입력값계산결과
평균 처리량1,000,000 ÷ 86,400약 11.6 msg/s (피크는 별도로 측정)
일 유입량1,000,000 × 2KB약 2GB/일
월 유입량2GB × 30약 60GB/월 (전송량 계산에 사용)
보존 데이터2GB × 7일약 14GB
복제 3 적용14GB × 3약 42GB (+ 여유 공간, 인덱스·오버헤드)

여기서 흔한 실수는 월 유입량(60GB)에 보존 일수를 다시 곱하는 것이다. 보존 7일이면 디스크에 남는 것은 7일치(약 14GB, 복제 포함 약 42GB)다. 이 규모에서는 스토리지보다 브로커 인스턴스의 최소 구성(보통 3노드)과 사람의 운영 시간이 비용을 좌우한다.

청구서에서 놓치기 쉬운 항목:

  1. AZ 간 전송료: 복제 계수 3을 서로 다른 AZ에 두면 프로듀서 → 리더, 리더 → 팔로워, 컨슈머 읽기 경로마다 AZ 간 트래픽이 생길 수 있다. 클라우드별 단가를 확인하고, Kafka는 client.rack으로 가까운 레플리카에서 읽도록(follower fetching) 줄일 수 있다.
  2. 관리형 서비스의 과금 단위: 브로커 시간, 파티션 시간, 저장 GB, 처리 GB 등 서비스마다 다르다. 같은 워크로드 표를 각 서비스의 공식 가격 계산기에 넣어 비교한다.
  3. 자체 운영의 인건비: 인스턴스 비용이 가장 낮아도 업그레이드, 디스크 확장, 장애 대응을 맡는 시간이 월 몇 시간인지 같이 적는다.

선택 후 첫 주에 확인할 운영 지표

제품꼭 볼 지표이상 신호
Kafka컨슈머 lag, under-replicated partitions, 디스크 사용률lag가 계속 증가, URP > 0 지속
RabbitMQ큐 깊이(ready/unacked), 메모리·디스크 알람, 연결/채널 수unacked가 계속 증가(컨슈머 정지), 알람으로 publish 차단
NATS JetStream컨슈머 pending/ack pending, 재전송 수, 스트림 크기ack pending 증가, max deliver 도달
Redis Streams스트림 길이(XLEN), PEL 크기(XPENDING), 메모리PEL이 줄지 않음(죽은 컨슈머), maxmemory 근접

Kafka 컨슈머가 리밸런스를 반복한다면 Kafka Consumer 리밸런싱 실패 원인과 튜닝을 참고하자.

자주 묻는 질문

Q. RabbitMQ도 리플레이가 되나요? A. RabbitMQ Streams(3.9+)는 메시지를 남겨 두고 오프셋으로 다시 읽을 수 있습니다. 클래식·쿼럼 큐는 ack 후 메시지가 삭제되므로 리플레이 용도가 아닙니다.

Q. Kafka는 전역 순서를 보장하나요? A. 파티션 내부 순서만 보장합니다. 같은 키(예: 주문 ID)를 같은 파티션으로 보내면 키 단위 순서를 얻습니다. 전역 순서가 필요하면 파티션을 1개로 둬야 하고 그만큼 병렬성을 잃습니다.

Q. NATS만으로 메시지 유실이 없나요? A. Core NATS는 at-most-once라 구독자가 없거나 끊기면 메시지가 사라집니다. 유실 방지가 필요하면 JetStream 스트림과 명시적 ack를 사용하세요.

기준일: 2026-10-15. 각 제품의 공식 문서(Apache Kafka, RabbitMQ, NATS, Redis)를 기준으로 했으며 버전별 기본값은 사용 중인 버전의 문서로 다시 확인하자.

확인 정보
✦ ✦ ✦
출처·검증 안내

글마다 출처와 확인 범위가 다릅니다. 아래에 확인일·확인 범위·출처가 기록된 글만 그 범위에서 확인된 것입니다. 기록이 없는 글은 적용 전 사용 중인 버전의 공식 문서로 직접 확인하고, 오류는 이메일로 알려주세요. 편집 정책 · 이메일로 제보

이 글에는 사람이 확인한 날짜·범위 기록이 아직 없습니다.

편집 책임 · Tive Fi·발행 ·
주제 관련 공식 문서(자동 연결 · 문장별 근거 아님)Redis 공식 문서 ↗Apache Kafka 공식 문서 ↗

댓글

첫 번째 댓글을 남겨보세요.