카테고리 없음

Queues vs Pub-Sub vs Streams

웅대 2025. 6. 8. 18:49
728x90

개요

메시지 패턴은 분리된 서비스들 간 메시지를 활용해서 정보를 공유하는 아키텍처입니다.

 

서비스에서 변화가 발생하면 메시지를 게시하고 게시된 메시지는 소비자들이 비동기적으로 처리합니다.

 

즉, 각 서비스 간 느슨한 결합을 통해 확장성과 유연성이 향상됩니다.

 

이 글을 읽기 앞서, 동기와 비동기에 대해 이해하는 것을 추천드립니다.

https://growth-coder.tistory.com/341 

 

동기 (Synchronous) vs 비동기 (Asynchronous)

개요이 글은 bytebytego의 동기 vs 비동기를 참고하여 작성했습니다. https://blog.bytebytego.com/p/synchronous-vs-asynchronous-communication Synchronous vs Asynchronous Communication: When to Use What?At some point, every system has to ma

growth-coder.tistory.com

 

주요 개념 

  • 생산자 (Producer) : 메시지를 생성하여 큐나 주제에 전달한다.
  • 소비자 (Consumer) : 메시지를 가져와서 처리한다.
  • 메시지 큐 (Message Queue) : 다른 서비스 간 메시지를 전달하기 위한 서비스.
  • 메시지 브로커 (Message Broker) : 메시지 큐를 확장한 기술로 광범위한 전송과 라우팅을 담당.

메시지 전송 보장 방식 (Delivery Semantics)

  • At most once : 메시지들은 한 번 전달되거나 아예 전달되지 않는다.
  • At least once : 메시지들은 한 번 이상 전달되어야 한다.
  • Exactly once : 메시지들은 오직 한 번 전달되어야 한다.

Queues

https://eda-visuals.boyney.io/visuals/queues-vs-streams-vs-pubsub

 

Queue 방식은 생산자가 메시지를 큐에 보내면 생산자는 큐에서 메시지를 가져와서 작업을 수행하는 방식입니다.

 

대형 마트의 계산대를 생각하면 쉽게 이해할 수 있습니다.

 

구매자(생산자)물건(메시지)을 계산하기 위해 줄을 서고 계산대(소비자)에서 순서대로 계산을 합니다.

 

대형 마트의 경우 계산대(소비자)를 여러 대 두어 계산해야 할 물건(메시지)가 많을 경우 병렬로 처리할 수 있습니다.

 

이 방식은 다음과 같은 특징을 갖습니다.

  • 한 소비자가 큐에서 메시지를 가져오면 그 메시지는 다른 소비자가 가져올 수 없습니다.
    즉, 같은 메시지가 여러 소비자에게 전달될 수 없습니다.
  • 먼저 들어온 메시지가 먼저 소비되는 선입선출 구조입니다.
  • 소비자에서 장애가 발생하더라도 메시지를 나중에 처리할 수 있습니다.
  • 어떠한 메시지가 계속해서 처리에 실패한 경우 이 메시지를 큐에서 삭제합니다.

queues 방식은 메시지가 딱 한 번 처리되어야 할 때 적합한 방식입니다.

  • 백그라운드 작업 (이메일 시스템)
  • 작업을 병렬로 처리해야 할 때
  • 서비스에 부하가 걸릴 때

pub-sub

https://eda-visuals.boyney.io/visuals/queues-vs-streams-vs-pubsub

 

메시지를 여러 개의 소비자에게 전달할 때 사용되는 구조입니다.

 

앞서 배운 queues의 경우 하나의 메시지는 오직 한 번만 처리된다고 했습니다.

 

하지만 pub-sub 구조의 경우 하나의 메시지가 여러 소비자에게 전달되어 처리될 수 있습니다.

 

소비자가 특정 주제(topic)를 구독하면 이 주제로 전달되는 메시지를 받을 수 있습니다.

 

쇼핑몰에서 물건을 살 때, 다음과 같은 동작이 필요하다고 합시다.

  • 재고 변화
  • 구매 알림
  • 배송

각 동작을 처리하는 소비자들은 같은 구매 topic을 구독하여 같은 그룹에 속하게 되고 구매 topic에 구매 메시지를 보내면 이 메시지가 같은 그룹 내부 모든 소비자들에게 전달됩니다.

 

그리고 위 3가지 동작이 각 소비자들로부터 병렬로 처리됩니다.

 

pub-sub의 경우 소비자를 추가하는 것도 쉽습니다.

 

위 3가지 동작 이외에 추가적인 동작이 필요하다면 해당 동작을 하는 소비자를 만들어서 같은 구매 topic을 구독하면 됩니다.

 

queues의 경우 여러 소비자들의 역할은 동일하기 때문에 각 메시지들은 오직 한 번만 처리됩니다.

 

그러나 pub-sub의 경우 여러 소비자들의 역할이 다르기 때문에 각 메시지들은 모든 소비자가 한 번씩 처리합니다.

 

pub-sub 방식은 하나의 메시지를 처리하기 위해 여러 개의 독립적인 동작이 필요할 때 유리합니다.

 

예를 들어 다음과 같은 상황들이 있습니다.

  • 알림을 인앱 알림, 이메일, 문자로 보내야 할 때
  • 이벤트가 발생했을 때, elastic search에 로깅하고 s3에 아카이빙 해야 할 때
  • sns에 사진을 업로드 했을 때, 친구들에게 알림을 보내주고 타임라인을 갱신하고 로깅해야 할 때

Streams

https://eda-visuals.boyney.io/visuals/queues-vs-streams-vs-pubsub

Event Stream은 실시간으로 처리 수집되고 처리되는 지속적인 데이터의 흐름입니다.

 

로그와 같이 시스템에서 발생한 이벤트를 시간 순서대로 계속 저장하고 각 이벤트들은 소비된 후 제거되지 않습니다.

 

특정 기간 동안 발생한 모든 이벤트를 시간 순서대로 보존하고 있기 때문에 언제든지 과거 시간대의 이벤트들을 확인할 수 있습니다.

 

  • 과거 데이터들을 가지고 다시 작업을 수행할 수 있습니다.
  • 특정 시간대에 무엇이 발생했는지 추적할 수 있습니다.
  • 데이터 감사에 적합합니다.

 

Queues vs Pub-Sub vs Streams

  메시지 큐 Pub-Sub 이벤트 스트림
전달 모델 1:1 통신, 메시지 확인 시 삭제. 1:N 통신, 각 구독자가 메시지 복사본 처리.
1:N 통신, 공유/내구성 있는 로그에서 읽기.
순서 보장 큐별 FIFO 목표 (재시도 시 깨질 수 있음), 전역적 일관성 아님. 구독자 간 전역 순서 보장 안 함 (일부 예외).
파티션 내 강력한 순서 유지.
재생 가능성 메시지 확인 시 폐기, 재생 불가. 브로커에 따라 다름 (제한적 재생 가능).
최고 수준의 재생 가능 (오프셋/타임스탬프 기반).
대기 시간
및 처리량
낮은 대기 시간, 병렬 소비자 수에 따라 처리량 확장. 낮은 대기 시간, 중간 처리량 (팬아웃/느린 구독자 문제 가능).
높은 처리량 (수백만/초), 대기 시간은 버퍼링 등에 따라 가변.

 

이제 이러한 메시지 패턴을 구현할 수 있는 대표적인 도구인 rabbitMQ와 kafka에 대해 알아봅시다.

 

RabbitMQ

AMQP는 메시지 지향 미들웨어(Message Oriented Middleware)에서 메시지 브로커 간 통신을 표준화하기 위해 설계된 프로토콜입니다.

 

서로 다른 서비스 간 소통할 때, 다른 방식을 사용하게 되면 불편하기 때문에 이러한 통신을 표준화기 위한 프로토콜이 AMQP입니다.

 

RabbitMQ는 AMQP 프로토콜을 구현한 대표적인 메시지 브로커입니다.

 

https://www.cloudamqp.com/img/blog/exchanges-topic-fanout-direct.png

RabbitMQ의 exchange와 그 종류는 아래와 같습니다.

  • exchange : 생산자가 메시지를 게시한 뒤, 큐나 스트림으로 라우팅하는 역할
    • direct : 바인딩의 라우팅 키와 정확히 일치하는 라우팅 키를 사용하여 하나 이상의 바인딩된 큐, 스트림 또는 Exchange로 라우팅한다.
    • topic : 메시지의 라우팅 키와 바인딩 시 사용된 라우팅(바인딩) 키 패턴 간의 패턴 매칭을 사용하여 라우팅한다.
    • fanout : 자신에게 발행된 모든 메시지를 바인딩된 모든 큐, 스트림 또는 Exchange에 복사하여 라우팅합니다.

 

 

 

Apache Kafka

https://www.geeksforgeeks.org/kafka-architecture/

 

Apache Kafka는 실시간 데이터 파이프라인 및 스트리밍 애플리케이션 구축을 위한 분산 스트리밍 플랫폼입니다.

 

  • 카프카 클러스터 (Kafka Cluster): 여러 카프카 브로커로 구성된 분산 시스템. 실시간 스트리밍 데이터 저장 및 처리 담당.
  • 브로커 (Brokers): 카프카 클러스터 구성 서버. 데이터 수신, 저장, 제공 담당. 생산자/소비자 읽기/쓰기 작업 처리. 데이터 복제 관리.
  • 토픽 및 파티션 (Topics and Partitions): 카프카 데이터는 토픽으로 구성. 토픽은 생산자 데이터 발행, 소비자 데이터 읽는 논리적 채널. 각 토픽은 파티션으로 나뉨. 파티션은 카프카 병렬 처리 기본 단위. 파티션 통해 데이터 여러 브로커에 분산시켜 수평적 확장 가능.
  • 생산자 (Producers): 카프카 토픽에 데이터 발행.
  • 소비자 (Consumers): 카프카 토픽 구독하고 데이터 처리.
  • 오프셋 (Offsets): 파티션 내 각 메시지에 할당되는 고유 식별자. 오프셋 사용하여 토픽에서 메시지 소비 진행 상황 추적.

Apache Kafka vs RabbitMQ

  Apache Kafka RabbitMQ
기본 설계 스트림 기록의 데이터 처리 가능한 내구성 우수 메시지 브로커 시스템.
간단한 아키텍처로 복잡한 메시지 라우팅 제공.
성능 초당 수백만 개의 메시지 전송 가능. 순차 디스크 I/O 사용하여 높은 처리량 제공.
초당 수백만 개 가능하나 여러 브로커 필요. 평균 초당 수천 개. 대기열 혼잡 시 속도 저하.

 

출처

https://www.cloudamqp.com/

https://eda-visuals.boyney.io/visuals/queues-vs-streams-vs-pubsub

https://blog.bytebytego.com/p/messaging-patterns-explained-pub

https://dev-gallery.tistory.com/33

https://www.cloudamqp.com/blog/amqp-vs-mqtt.html

https://www.geeksforgeeks.org/kafka-architecture/

https://aws.amazon.com/ko/compare/the-difference-between-rabbitmq-and-kafka/

728x90