RabbitMQ에 대해서 알아보자(vs Kafka)

Jeonghwa·2024년 4월 7일
2

RabbitMQ

목록 보기
1/3

RabbitMQ

  • AMQP(Advanced Message Queuing Protocol)를 구현한 오픈소스 메시지 브로커이다.
  • 메시지 지향 미들웨어(MOM)의 한 형태로 시스템간 메시지를 비동기적으로 교환할 수 있게 해준다.
  • 분산 시스템에서 컴포넌트 간 결합도를 낮추고 확장성을 제공한다.
  • 일반적으로 Producer가 메시지를 발행하면 Consumer에게 이를 전달하는 브로커 역할을 한다.

이는 처리 시간이 긴 요청을 분리하거나, 하나의 요청을 여러 클라이언트에게 비동기적으로 전달해야할 때 유용하게 사용됩니다.

저 또한 진행하고 있는 프로젝트에서 공간예약 시 알림을 발생하는데 예약행위와 알림발생을 분리하고 싶어 메세지큐를 도입하였습니다.

AMQP란?

클라이언트와 메시지 지향 미들웨어(MOM)사이에서 데이터를 주고받기 위한 메시징 프로토콜입니다.

RabbitMQ 동작방식

  • Producer: 메시지 발생자. 보내고자하는 메세지를 Exchange에 발행한다.
  • Exchange: 메시지를 받고 이를 Binding규칙에 맞게 Queue에 분배한다.
  • Queue: 메세지를 저장하며, Queue를 listen하고있는 Consumer에게 데이터를 전달한다.
  • Consumer: 메시지를 받고 처리하는 소비자.

Exchange 속성

Exchange는 Producer에게 1차적으로 메시지를 받고 이를 규칙에 맞게 Queue에 분배하는 집배원같은 역할을 합니다.

아래 화면에서 Exchange에 대한 설정이 가능하며 크게 4가지 Type을 갖습니다. 해당 부분은 아래에서 더 설명하겠습니다.

  • Name: Exchange 이름
  • Type: 메시지 분배 방식(direct, fanout, headers, topic)
  • Durability: 브로커가 재시작되어도 유지되어있는지 여부
    • Durable: 브로커가 재시작되어도 디스크에 저장되어 유지됨
    • Transient: 브로커가 재시작되면 사라짐
  • Auto-delete: 하나이상의 Queue 또는 Exchange에 바인딩되었다 언바인딩되면 자동 삭제
  • Internal: Client는 해당 Exchange에 직접 Publish하지 못하며, 오로지 Exchange간의 바인딩에만 사용가능
  • Arguments: Arguments 설정
    • alternate-exchange: 대체 Exchange 설정. 만약 바인딩된 큐 또는 바인딩 조건이 일치하는 큐가 없다면 대체 Exchange로 메시지를 전달합니다.

Queue 속성

Queue는 Exchange로 부터 메시지를 전달받으며 Consumer가 처리하기 전까지 메시지를 저장합니다.

아래 화면에서 Queue에 대한 설정을 할 수 있으며, Arguments를 통해 다양한 기능을 줄 수 있습니다.

  • Name: Queue 이름
  • Type: Queue 타입(Classic, Quorum, Stream)
    • 보통 Classic 타입이 사용됩니다.
  • Durability: 브로커가 재시작되어도 유지되어있는지 여부
    • Durable: 브로커가 재시작되어도 디스크에 저장되어 유지됨
    • Transient: 브로커가 재시작되면 사라짐
  • Arguments: Arguments 설정
    • x-expires: 설정된 시간동안 큐가 사용되지 않으면 자동으로 삭제됩니다.(ms단위)
    • x-message-ttl: 설정된 시간동안 publish된 메시지가 큐에 살아있으면 자동으로 삭제됩니다.(ms단위)
    • x-overflow: 큐의 max-length에 도달했을 때 동작을 결정합니다. (유효값: drop-head, reject-publish, reject-publish-dlx)
    • x-single-active-consumer: 설정된 경우, 한번에 한명의 소비자만 큐를 소비합니다. 만약 해당 소비자가 취소되거나 종료되면 등록된 다른 소비자가 장애조치(fail over)를 할 수 있습니다.
    • x-dead-letter-exchange: 메시지가 거부되거나 만료된 경우, 해당 메시지가 republish될 Exchange를 설정합니다.
    • x-dead-letter-routing-key: 메시지가 거부되거나 만료된 경우, DLX로 보내질 때 사용할 라우팅 키입니다. 만약 설정되지 않은 경우 원래 라우팅키가 사용됩니다.
    • x-max-length: 큐에 저장할 수 있는 메시지 최대 개수입니다.
    • x-max-length-bytes: 큐에 저장할 수 있는 메시지 최대 크기입니다. (byte단위)

Exchange 4가지 Type

Direct

Direct는 특정 큐에 메시지를 보낼 수 있습니다. 메시지에 라우팅 키를 작성하여 보내면, 바인딩된 라우팅키와 일치하는 큐로 메시지를 보내줍니다. 주의할 점은 어떤 라우팅키와도 일치하지 않으면 메시지는 폐기됩니다.

블로깅 시스템에 사진을 업로드할 경우 png, jpg 파일은 바로 썸네일을 생성하고 svg 파일은 변환작업이 필요하다는 상황을 가정해봅시다. 위 상황엔 확장자를 라우팅키로 Direct Exchange를 두는것이 적절합니다.

라우팅키 설정방법

설정할 Exchange의 Bindings 탭에 들어가 Queue이름과 매칭할 라우팅키를 입력해주면됩니다.

Topic

Direct와 유사하게 특정 큐에 메시지를 보낼 수 있습니다. 메시지에 라우팅 키를 작성하여 보내면, 바인딩된 라우팅키 패턴과 일치하는 모든 큐에 메시지를 보내줍니다.

라우팅키 패턴에는 2가지 규칙이 있습니다.

  • *(별표): 정확히 하나의 단어 대체 가능
  • #(해시) : 무수히 많은 단어 대체 가능

Direct 예시에 몇 가지 요구사항을 더해봅시다. 모바일 앱에서 온 사진은 이미지 필터 적용이 필요하며, 큰 크기의 svg는 로깅이 필요합니다. 위와 같은 경우 Topic Exchange를 두고 아래와 같이 라우팅키 패턴을 작성해 주면 요구사항을 만족할 수 있습니다.

만약 mobile.large.svg 라우팅키를 가진 메시지가 들어온다면? vector, mobile, log 큐 모두에게 전달될 것입니다.

Fanout

Fanout은 Exchange에 바인딩된 모든 큐에 메시지를 보냅니다.
모든 큐에 동일하게 메시지를 전달하기 때문에 라우팅 키는 무시됩니다. 만약 N개의 큐가 연결되어있다면 메시지는 N개 복사되어 각 큐로 전달됩니다.

HR시스템에 신규입사자 또는 퇴직자가 발생할 경우 회계/마케팅시스템 모두 해당 데이터를 처리해야한다는 상황을 가정해봅시다. 위 상황엔 두 시스템 모두 메시지를 받아야하므로 Fanout Exchange를 두는 것이 적절합니다.

Headers

Header 방식을 사용하면 메시지의 라우팅 키는 무시되고, 대신 헤더에 정의된 기준을 사용하여 헤더 값과 Exchange에 바인딩된 규칙을 비교합니다.

Header Exchange는 기본적으로 x-match Argument를 사용하며, 기본 값은 all 입니다. 이는 지정된 모든 조건을 만족해야 메시지가 라우팅 될 수 있다는 것을 의미하며 AND조건으로 볼 수 있습니다.
다른값으로는 any가 있으며, 지정된 조건을 하나라도 만족하면 메시지가 라우팅 될 수 있습니다. 즉 OR조건으로 볼 수 있습니다.

만약 위와 같이 바인딩 규칙을 만들게되면 아래와 같이 전달됩니다.

RabbitMQ vs Kafka

메세징 시스템엔 RabbitMQ말고도 대표적으로 Kafka가 존재합니다. 이 둘의 차이에 대해서도 살펴보고 적용하고자 하는 시스템에 적합한 기술이 무엇인지 생각해봅시다.

Message Retention

Kafka

  • Kafka는 메시지 보존 정책에 따라 메시지가 유지됩니다.
  • 즉, 모든 메시지는 설정된 특정 기간동안 디스크에 저장됩니다.
  • 만약 데이터를 주간 단위로 저장해야한다면, 메시지 보존 기간을 7일로 설정할 수 있습니다.
  • 위 사진처럼 Consumer가 M1, M2, M3를 처리하면 메시지는 디스크에 설정된 기간동안 남아있게 되기때문에 다른 Consumer(심지어 같은 Consumer)도 M1, M2, M3를 소비할 수 있습니다.

RabbimtMQ

  • RabbitMQ는 Consumer가 성공적으로 처리했음을 확인할 때까지 메모리나 디스크에 메시지를 저장합니다.
  • 즉, Consumer가 메시지를 한번 소비하면 사라집니다.
  • 따라서 같은 메시지를 처리하려면 Producer가 다시 메시지를 발행해야합니다.

Message Routing

Kafaka

  • Kafka는 메시지에 대한 라우팅 메커니즘이 없습니다.
  • Producer가 어떤 Topic(또는 Partition)에 쓸지 알려주고 Kafka는 그 특정 Topic에 메시지를 발행합니다.
  • Topic: 메시지가 분류되어 발행되는 카테고리로, 소비자(Consumer)가 구독할 수 있는 논리적인 채널입니다.
  • Partition: 토픽 내에서 메시지를 세분화하여 저장하는 물리적 단위로, 메시지의 순서와 분산 처리를 가능하게 합니다.

RabbitMQ

  • RabbitMQ는 Exchange를 사용하여 하나 이상의 큐로 메시지를 라우팅하는 라우팅 메커니즘을 가지고 있습니다.
  • 위에서 본 Direct, Topic, Fanout, Headers 타입을 기반으로 라우팅키 또는 헤더를 사용해 다양한 메커니즘으로 메시지를 라우팅할 수 있습니다.

Multiple Consumers

Kafka

  • Kafka는 파티셔닝을 사용하여 여러 Consumer에게 메시지를 발생합니다.
  • 그림을 보면 한 Topic은 여러 Partition을 가질 수 있으며, 각 Partition은 Consumer Group당 오직 하나의 Consumer를 가질 수 있습니다.
  • 따라서 Kafka에선 메시지 순서가 보장됩니다.

RabbitMQ

  • RabbitMQ는 하나의 Queue에 여러 Consumer가 있을 수 있습니다.
  • 이는 Producer가 빠르고 Consumer가 느린 경우 유용할 수 있습니다.
  • 하지만 여러 Consumer가 있기 때문에 경쟁 소비자(Competing Consumers)패턴이 발생하여 큐의 메시지가 순서대로 처리되지 않을 수 있습니다.

Consumer Push/Pull Model

Kafka

  • Kafka Consumer는 Topic과 Partition으로부터 메시지를 끌어당깁니다. (Pull)
  • Pull Model은 한 Partition에 하나의 Consumer만 접근할 수 있기 때문에 메시지 순서를 보장합니다.

RabbitMQ

  • RabbitMQ는 등록된 Consumer에게 메시지를 밀어 넣습니다. (Push)
  • Consumer가 메시지를 처리할 수 있는 속도보다 Procuder가 메시지를 발행하는 속도가 빠르게 되면 Overflow가 생길 수 있으므로 이를 방지하기 위해 prefetch limit을 설정할 수 있습니다.
  • Push Model은 메시지 워크로드가 Consumer사이에 공평하게 분배되도록 보장합니다.

RabbitMQ는 3.11부터는 Stream과 단일 소비자 활성 기능이 추가되어 Kafka동작과 비슷하도록 개선하였습니다.

그래서 둘중에 무엇을 써야할까?

시스템의 성격에 따라 적합한 메시징 시스템이 다릅니다.

빠른 거래(fast transaction)가 필요한 회사들은 Kafka를 핵심 메시징 시스템으로 선호하는 반면, 거래량이 적은(lower transaction) 회사들은 RabbitMQ를 선택하는 경향이 있습니다.

이는 RabbitMQ가 매니징이 다소 쉽기때문입니다. 설치하면 대부분 메시지 브로커로서 문제없이 잘 작동합니다. 반면 Kafka는 클러스터 복제, Producer 및 Consumer 구성 등 다양한 관리작업을 필요로 합니다.

하지만 Kafka는 확장성이 뛰어나고 대규모 데이터 스트리밍 처리에 주로 사용됩니다. 예를들어 은행은 atm, 신용카드 등 다양한 채널에서 발생하는 거래를 Kafka로 스트리밍하여 사기 가능성을 분석할 수 있습니다.

둘다 널리 사용되는 기술이지만, 상대적으로 RabbitMQ가 러닝커브가 조금 더 낮고 적용하고자하는 기능이 대규모 데이터 스트리밍 처리를 필요로하지 않기 때문에 RabbitMQ가 프로젝트에 적합하다고 판단하여 선택하였습니다. 하지만 추후 RabbitMQ만으로는 트래픽 감당이 힘들 경우 Kafka로 변경이 필요할 수 있을 거같다는 생각이듭니다.

참고:

profile
backend-developer🔥

0개의 댓글

관련 채용 정보