메시지 플랫폼

GreenBean·2023년 2월 17일
0
post-thumbnail

메시지 플랫폼

RabbitMQ, Redis, Kafka의 특징
[Server/MSA] RabbitMQ, Redis, Kafka 란?
MQ 비교 (Kafka, RabbitMQ, Redis)
PUB/SUB, 잘 알고 쓰자!

  • RabbitMQ, Redis, Kafka 같은 기술을 메시지 플랫폼이라고 함
    • 메시지 플랫폼은 2가지 종류가 존재
      • 메시지 브로커
      • 이벤트 브로커
    • 메시지 브로커이벤트 브로커의 역할을 할 수 없지만 이벤트 브로거메시지 브로커의 역할을 할 수 있음
  • 서버에 많은 요청이 한 번에 들어오면 처리하지 못할 수 있음
    • 처리하지 못한 데이터는 손실되어 서비스에 치명적인 영향을 줄 수 있음
    • 따라서 유저의 요청이 들어오면 일단 요청을 큐에 넣어놓고 서버가 처리할 수 있을 때 데이터를 가져감
    • 메시지는 삭제되지만 이벤트는 삭제하지 않음
    • 메시지 브로커이벤트 브로커가 될 수 없으나 이벤트 브로커메시지 브로커가 될 수 있음
      • 메시지는 삭제되고 이벤트는 삭제되지 않기 때문
  • 메시지 큐 모델Pub/Sub 이벤트 스트림 모델을 구분할 수 있음

Tip! Pub/Sub 모델 의 구조

  • 이벤트 (=메시지) 를 발행하는 Publisher 가 존재하며 Publisher 는 특정 Channel ( 혹은 Topic ) 에 이벤트를 전송
  • 특정 Channel ( 혹은 Topic ) 을 구독하는 Subscriber 가 존재하며 Publisher 에 관계 없이 발행된 이벤트를 받을 수 있음
  • 이때 구체적인 Pub ( 발행 ) / Sub ( 구독 ) 방식이 각 서비스마다 다른데 대표적으로 Rediskafka 가 있음

메시지 브로커

  • RabbitMQ, Redis
  • 대규모 메시지 기반 미들웨어 아키텍쳐에서 사용
    • 미들웨어: 애플리케이션과 이들이 동작하는 인프라 간의 효율적인 연결을 위해 존재하는 소프트웨어
      • 예시: 메시지 플랫폼, 인증 플랫폼, 데이터베이스
  • 메시지를 받아서 적절히 처리하면 짧은 시간 내에 메시지가 삭제되는 특징이 있음
    • 데이터 손실의 위험 존재
  • 메시지를 받아서 처리하면 짧은 시간 안에 메시지가 삭제됨
    • 손실되면 안되는 요청을 처리할 때에는 주의해야 함

Tip! 마이크로 서비스 통신: 동기 VS 비동기

  • 동기식
    • 요청을 보내면 응답이 올 때까지 기다리고 처리
    • HTTP 위에서 REST 프로토콜을 사용
  • 비동기식
    • 응답과 상관없이 요청을 보냄
    • 분산형 시스템에 적합하고 메시지 브로커 를 통해서 메세지를 관리
      • 메세지 브로커: 송신자의 메세지 프로토콜 형식에서 수신자의 메세지 프로토콜 형식으로 변환하는 중간 모듈
  • 무엇을 선택?
    • 마이크로 서비스를 구성하는 방법과 인프라 ∙ 대기시간 ∙ 규모 ∙ 종속관계 등 다양한 환경을 고려해서 선택해야 함
    • 비동기식 통신이 설정하기 더 복잡하고 더 많은 기술 스택을 사용해야 함
      • 하지만 마이크로 서비스에서 더 많은 장점을 갖고 있음
  • 비동기식 통신의 장점
    • 논블로킹: 기다리지 않고 다른 작업을 수행 가능하니 효율이나 반응 속도가 뛰어남
    • 확장성: 동기식 보다 결합도가 떨어지기 때문에 확장성이 좋음

이벤트 브로커

  • kafka
  • 이벤트 또는 메시지라고 불리는 정보를 하나만 보관하고 인덱스를 통해 개별 엑세스를 관리
    • 업무상 필요한 시간 동안 이벤트를 관리
    • 메시지 브로커와 다르게 이벤트가 삭제되지 않는다는 특징 존재
    • 서비스에세 발생하는 이벤트를 데이터베이스에 저장하듯이 이벤트 브로커의 큐에 저장
  • 이벤트를 저장함으로써 얻는 장점
    • 딱 한번 일어난 이벤트 데이터를 브로커에 저장함으로써 모든 데이터 요소를 한 곳에서만 제어 또는 편집하도록 조작하는 관례 ( 단일 진실 공급원 ) 에 맞게 동작
    • 장애가 발생했을 때 장애가 일어난 지점부터 재처리 가능
    • 많은 양의 실시간 스트림 데이터를 효과적으로 처리 가능
  • 이벤트를 받아서 처리하면서 이벤트를 삭제하지 않음
  • 손실되면 안되는 요청을 처리할 때 좋음

생산자와 소비자

  • 생산자: 데이터를 메시지 큐에 전달하는 입장
  • 소비자: 메시지 큐에서 데이터를 가져오는 입장

📮 RabbitMQ

  • 메시지 브로커
    • 구성이 쉬움
    • 복잡한 라우팅을 지원
    • 오래되었고 안정성이 높음
    • 20K/sec 정도의 속도를 보임
    • 소비자 중심의 설계
    • 데이터 손실의 위험성
    • 성능 문제
  • 응용 프로그램 ( applications ) 에게 메시지를 주고 받을 수 있으며 메시지가 수신될 때까지 안전하게 있을 수 있도록 하는 공용 플랫폼 ( common platform ) 을 제공
    • 메시지를 다른 대기열로 보낼 수 있는 라우팅 시스템을 갖추고 있음
    • 우선 순위가 높은 메시지를 먼저 사용하기 위해 작업자가 사용할 수 있는 메시지의 우선 순위를 지원
    • 메시지 브로커로서 Redis 와 비교할 때 훨씬 더 다양한 기능을 제공
    • 크고 복잡한 메시지에 적합
  • RabbitMQ 는 오픈 소스 메시지 브로커 소프트웨어
    • 구성이 쉽고 안정적
  • 구성
    • Producer 는 요청을 보내는 주체
    • Consumer 는 생산자로부터 메시지를 받아 처리하는 주체
    • Exchange 는 메세지를 전달하고자 하는 목적지(큐)에 전달하는 주체
    • Queues 는 메세지를 쌓는 주체

  • 메시지 처리 과정
    • Producer 가 메세지 보냄
    • Exchange 에서 해당하는 키에 맞게 큐에 분배 ( 바인딩 또는 라우팅 )
      • topic 모드: Routing Key 가 정확히 일치하는 Queue 에 메시지 전송 ( Unicast )
      • direct 모드: Routing Key 패턴이 일치하는 Queue 에 메시지 전송 ( Multicast )
      • headers 모드: Key-Value 로 이루어진 header 값을 기준으로 일치하는 Queue 에 메시지 전송 ( Multicast )
      • fanout 모드: 해당 Exchange 에 등록된 모든 Queue 에 메시지 전송 ( Broadcast )
    • 해당 Queue 에서 Consumer 가 메세지를 받음
  • 특징
    • MQ Server 가 종료 후 재기동 하면 기본적으로 Queue 내용은 모두 제거
  • RabbitMQAMQP 를 구현
    • AMQP ( Advanced Message Queuing Protocal ) 는 메시지 지향 미들웨어를 위한 개방형 표준 응용 계층 프로토콜

📮 Redis

  • 메시지 브로커
  • 메모리 기반의 딕셔너리 구조 데이터 관리 시스템
    • 처리 속도가 빠름
    • 캐시의 역할도 가능
    • 명시적으로 데이터 삭제 가능
    • 메모리 기반이므로 서버가 다운되면 Redis 내의 모든 데이터가 사라짐
  • 디스크에 상주하는 인메모리 데이터베이스
    • 컴퓨터 메모리를 이용한 ( in-memory ) Cache 서버
    • Key-Value 를 이용해 Celery 가 처리할 작업을 Celery 에게 보낸 후 Cache 에서 해당 Key 를 제거하는 방식으로 작동
      • Redis 는 데이터 검색을 위해 데이터베이스에 접근하기 전 메모리에서 Cache 를 가져다 쓴다는 점에서 속도가 빠름
      • 매우 빠른 서비스 및 메모리 내 기능을 제공하기 때문에 지속성이 중요하지 않고 약간의 손실을 견딜 수 있는 짧은 보존 메시지에 적합
      • 큰 메시지를 처리할 때는 대기 시간이 오래 걸림
  • Key-Value 구조의 비정형 데이터를 저장하는 비관계형 데이터베이스 관리 시스템
  • 캐시 역할로 많이 사용
  • 사용자가 많은 서비스에서 데이터베이스가 과부하될 때 캐시 역할로 많이 사용됨
  • Single Threaded 기반으로 운영
    • 한 번에 하나의 명령만 처리할 수 있음
  • 구성 요소
    • Publisher 는 메세지를 게시 ( Pub )
    • Channel 은 메세지를 쌓아두는 Queue
    • Subscriber 는 메세지를 구독 ( Sub )
  • 동작
    • PublisherChannel 에 메세지 게시
    • 해당 채널을 구독하고 있는 Subscriber 가 메세지를 Sub 해서 처리함
  • 특징
    • Channel 은 이벤트를 저장하지 않음
    • Channel 에 이벤트가 도착했을 때 해당 채널의 Subscriber 가 존재하지 않는다면 이벤트 사라짐
    • Subscriber 는 동시에 여러 채널을 구독할 수 있으며 특정한 채널을 지정하지 않고 패턴을 설정하여 해당 패턴에 맞는 채널을 구독할 수 있음

📮 Kafka

  • 이벤트 브로커
  • 구독 방식의 비동기식 구성
    • 분산 처리에 효과적
    • 생산자 중심의 설계
    • 이벤트 기반 마이크로 서비스 아키텍쳐로 발전하는데 큰 도움이 될 수 있음
    • 100K/sec 정도의 속도
  • 아파치 소프트웨어 재단이 스칼라로 개발한 오픈 소스 메시지 브로커 프로젝트
  • 개념
    • Pub/Sub 모델의 메세지 큐
    • 분산 환경에 특화되어 있는 특징
    • RabbitMQ 와 같은 다른 메시지 큐보다 빠름
    • 클러스터 구성 ∙ Fail-Over ∙ Replication 과 같은 기능 존재
  • 구성 요소
    • Eventkafka 에서 ProducerConsumer 가 데이터를 주고받는 단위 (=메시지)
    • Producerkafka 에 이벤트를 게시 ( POSTPOP ) 하는 클라이언트 어플리케이션
    • ConsumerTopic 을 구독하고 이로부터 얻어낸 이벤트를 받아 ( Sub ) 처리하는 클라이언트 어플리케이션
    • Topic 은 이벤트가 모이는 곳
      • ProducerTopic 에 이벤트를 게시하고 ConsumerTopic 을 구독해 이로부터 이벤트를 가져와 처리
      • 게시판 같은 개념
    • Topic 은 여러 Broker 에 분산되어 저장되는데 이렇게 분산된 TopicPartition 이라고 함
    • Zookeeper 는 분산 메시지의 큐의 정보를 관리

  • 하나의 토픽에 여러 개의 파티션을 나눠서 이벤트 (=메시지) 를 쓰는 이유
    • kafka 의 토픽에 메세지가 쓰여지는 것도 어느 정도 시간이 소비됨
    • 몇 천건의 메세지가 동시에 kafkawrite 되면 병목 현상이 발생할 수 있음
    • 따라서 파티션을 여러개 두어서 분산 저장함으로써 write 동작을 병렬로 처리할 수 있음
      • 다만 한 번 늘린 파티션은 절대 줄일 수 없기 때문에 운영 중에 파티션을 늘려야 하는건 충분히 고려해서 실행해야 함
    • 파티션을 늘렸을 때 메세지가 round-robin 방식으로 쓰여짐
      • 따라서 메세지의 순서가 보장되지 않음
  • Fail-Over 시 마지막 위치부터 다시 메세지를 불러올 수 있음
    • 각 파티현에 존재하는 offset 의 위치를 통해 이전에 소비했던 offset 위치를 기억하고 관리
    • 따라서 Consumer 가 죽었다가 다시 살아나도 전에 마지막으로 읽었던 위치에서부터 다시 읽어들일 수 있음

  • Consumer 그룹이 존재하는 이유
    • Consumer 의 묶음을 Consumer Group 이라고 함
    • Consumer Group 은 하나의 토픽에 대한 책임을 가지고 있음
      • 즉 어떤 Consumer 가 다운된다면 파티션 재조정 ( 리밸런싱 ) 을 통해 다른 Consumer 가 해당 파티션의 Sub 를 맡아서 함
    • offset 정보를 그룹 간에 공유하고 있기 때문에 다운되기 전 마지막으로 읽었던 메세지 위치부터 시작

Tip! 추가 내용

Tip! 추가 내용

Celery

  • CeleryPython 으로 작성된 분산 메시지 전달을 기반으로 한 비동기 작업 큐로 Worker 의 한 종류
  • 요청을 받은 뷰에서는 Broker 에게 해당 작업 실행을 위임하고 각 작업을 구분할 수 있는 Task ID 를 발급받게 됨
    • 해당 작업은 Broker 가 놀고 있는 Worker 에게 넘겨서 Worker 가 비동기로 수행하도록 함
  • Django 서버에서 Task 를 메시지 브로커를 통해 전달을 하면 하나 이상의 Celery Worker메시지 브로커 큐에 있는 Task 를 받아서 이를 관리
profile
🌱 Backend-Dev | hwaya2828@gmail.com

0개의 댓글