Kafka, Redis, RabbitMQ

hyelim·2023년 6월 29일
4
post-thumbnail

Kafka, Redis, RabbitMQ는 모두 메시지 큐(Message Queue) 형식의 시스템이다.
메시지 큐는 비동기 메시지 전달을 통해 여러 컴포넌트나 시스템 간에 데이터를 안전하고 효율적으로 교환하는 데 사용되는 소프트웨어 패턴인데
먼저 이러한 메시지큐, 메시지 와 이벤트 브로커에 대해 알아보자

메시지큐, 메시지/이벤트 브로커

이외에도 카프카를 이해하기 위해서는 메세지/이벤트 브로커와 메세지 큐에 대한 선제적인 이해가 필요하다

메시지큐

먼저 메시지 큐부터 살펴보자

메시지큐는 아래와 같은 형태이다.

메시지 지향 미들웨어(MOM : Message Oriented Middleware)를 구현한 시스템으로 프로그램(프로세스) 간의 데이터를 교환할 때 사용하는 기술이다

메시지 큐 구조

  1. producer: 정보를 제공하는 자

  2. consumer: 정보를 제공받아서 사용하려는 자

  3. Queue: producer의 데이터를 임시 저장 및 consumer에 제공하는 곳

메세지는 Endpoint 간에 직접적으로 통신하지 않고, 중간의 Queue를 통해 중개된다

메시지 큐 장점

  1. 비동기: queue라는 임시 저장소가 있기 때문에 나중에 처리 가능

  2. 낮은 결합도: 애플리케이션과 분리

  3. 확장성: producer or consumer 서비스를 원하는대로 확장할 수 있음

  4. 탄력성: consumer 서비스가 다운되더라도 애플리케이션이 중단되는 것은 아니며 메시지는 지속하여 MQ에 남아있다.

  5. 보장성: MQ에 들어간다면 결국 모든 메시지가 consumer 서비스에게 전달된다는 보장을 제공한다.

메시지브로커

메시지브로커의 경우 publisher가 생산한 메세지를 메세지 큐에 저장하고, 저장된 데이터를 consumer가 가져갈 수 있도록 중간 다리 역할을 해주는 브로커(broker)라고 볼 수 있다.

보통 서로 다른 시스템(혹은 소프트웨어) 사이에서 데이터를 비동기 형태로 처리하기 위해 사용한다. (대규모 엔터프라이즈 환경의 미들웨어로서의 기능)

이러한 구조를 보통 pub/sub 구조라고 하며 대표적으로는 Redis, RabbitMQ 소프트웨어가 있고, GCP의 pubsub, AWS의 SQS 같은 서비스가 있다.

이와 같은 메세지 브로커들은 consumer가 큐에서 데이터를 가져가게 되면 즉시 혹은 짧은 시간 내에 큐에서 데이터가 삭제되는 특징들이 있다.

이벤트브로커

이벤트 브로커 또한 기본적으로 메세지 브로커의 큐 기능들을 가지고 있어 메세지 브로커의 역할도 할 수 있다.

메세지 브로커와의 가장 큰 차이점은,이벤트 브로커는 publisher가 생산한 이벤트를 이벤트 처리 후에 바로 삭제하지 않고 저장하여, 이벤트 시점이 저장되어 있어서 consumer가 특정 시점부터 이벤트를 다시 consume 할 수 있는 장점이 있다. (예를 들어 장애가 일어난 시점부터 그 이후의 이벤트를 다시 처리할 수 있음)

또한 대용량 처리에 있어서는 메세지 브로커보다는 더 많은 양의 데이터를 처리할 수 있는 능력이 있다.
이벤트 브로커에는 Kafka, AWS의 kinesis 같은 서비스가 있다.

PUB/SUB

PUB/SUB은 이러한 메시지 기반 통신에서 사용되는 패턴이자, Publish/Subscribe(게시자/구독자) 패턴의 약어이다. 이 패턴은 메시지를 보내는 게시자(Publisher)와 해당 메시지를 수신하는 하나 이상의 구독자(Subscriber) 사이의 비동기적인 통신을 가능하게 합니다.

PUB/SUB의 구조는 아래와 같다.

  1. 이벤트(메시지)를 발행하는 Publisher가 존재하며, Publisher는 특정 Channel(혹은 Topic)에 이벤트를 전송한다.
  2. 특정 Channel(혹은 Topic)을 구독하는 Subscriber가 존재하며, Publisher에 관계없이 발행된 이벤트를 받을 수 있다.

Pub/Sub 모델의 구체적인 발행/구독 방식은 각 서비스 마다 다른데, 대표적으로 Kafka, Redis, RabbitMQ 등이 존재하며 각 아키텍쳐를 간단히 살펴보자

1. Kafka

카프카(Kafka)는 파이프라인, 스트리밍 분석, 데이터 통합 및 미션 크리티컬 애플리케이션을 위해 설계된 고성능 분산 이벤트 스트리밍 플랫폼이다.

Pub-Sub 모델의 메시지 큐 형태로 동작하며 분산환경에 특화되어 있다.

카프카의 탄생 배경

카프카의 탄생이전에는 아래의 왼쪽과 같은 그림의 구조를 사용했다

링크드인의 카프카 적용전 데이터 처리 시스템

하지만 왼쪽 그림처럼 point-to-point 구조를 사용하면 아래와 같이 구조가 너무 복잡하다. 아래는 링크드인의 카프카 적용전 데이터 처리 시스템의 모습이다

이 경우

  1. 시스템 복잡도의 증가
  2. 데이터 파이프라인 관리의 어려움

이 존재하기에 링크드인이 모든 시스템으로 데이터를 전송할 수 있고, 실시간 처리도 가능하며, 급속도로 성장하는 서비스를 위해 확장이 용이한 시스템을 만들자라는 목표로 카프카를 탄생시켰다

링크드인의 카프카 적용후 데이터 처리 시스템

아래는 카프카를 적용 후 링크드인의 데이터베이스 처리 시스템의 구조이다. 훨씬 간단하다.

이렇게 모든 이벤트/데이터의 흐름을 중앙에서 관리하는 카프카를 개발하였다.

카프카는 아래와 같은 특징들을 지닌다

카프카의 특징

Kafka에서는 Producer/Consumer라는 개념이 등장하는데, 각각 Publisher/Subscriber와 그 기능이 동일하다. Producer는 Topic에 이벤트를 보내고, 이 이벤트는 Topic의 각 Partition에 분산되어 저장된다. Topic을 구독하고 있는 Consumer group 내의 Consumer는 각각 1개 이상의 partition으로부터 이벤트를 가져온다. 만약 partition 개수보다 consumer 개수가 많다면, 아무 일도 하지 않는 consumer가 생기기 때문에, 항상 partition 수를 consumer보다 같거나 크게 해주는 것이 좋다.


1. publisher는 전달하고자 하는 메세지를 topic을 통해 카테고리화 한다.
2. subscriber는 원하는 topic을 구독함으로써 메시지를 읽어온다.
3. publisher와 subscriber는 오로지 topic 정보만 알 뿐, 서로에 대해 알지 못한다.
4. kafka는 broker들이 하나의 클러스터로 구성되어 동작하도록 설계
클러스터 내, broker에 대한 분산처리는 ZooKeeper가 담당한다.

이 같은 과정으로 카프카가 동작하는데 여기서 카프카가 대규모 트래픽 처리 및 분산 처리에 효과적이다는 것을 알 수 있다.

2. Redis(Remote Dictionary Server)

Redis 는 키(Key) - 값(Value) 쌍의 해시 맵과 같은 구조를 가진, 데이터베이스, 캐시, 메시지 브로커 및 스트리밍 엔진으로 사용되는 인메모리 데이터 구조 저장소이자 비관계형(NoSQL) 데이터베이스 관리 시스템(DBMS)이다

Redis에는 그룹이라는 개념이 존재하지 않고, 각 subscriber가 channel을 구독하고 있다. 이때 중요한 점은, Channel은 이벤트를 저장하지 않는다는 것이다. 만일 Channel에 이벤트가 도착했을 때, 해당 채널의 Subscriber가 존재하지 않는다면, 이벤트는 사라진다.

Redis의 Channel은 말 그대로, TV의 Channel을 생각하면 된다. 하루 종일 TV에서는 수백 개의 채널에서 방송이 방영된다. 각 방송사(Publisher)에서 방영하는 라이브 방송은, 해당 채널을 시청 중일 때만 볼 수 있다. 또한 같은 시간대에 같은 채널의 시청자(Subscriber)들은 모두 같은 방송을 볼 수 있다.

물론 위의 예시에서 다 담지 못하는 부분도 있다. subscriber는 동시에 여러 Channel을 구독할 수 있으며, 특정한 채널을 지정하지 않고 ‘패턴’을 설정하여 해당 패턴에 맞는 채널을 구독할 수도 있다.

KAFKA vs REDIS

Kafka와 Redis의 주된 차이점은 다음과 같다.

1. 이벤트의 저장 여부

Kafka는 발행된 이벤트가 각 Partition에 저장된다. 하지만 Redis는 발행된 이벤트를 저장하지 않기 때문에, 구독자가 없다면 해당 이벤트는 사라지고 만다. 따라서, 이벤트의 구독과 발행이 실시간으로 이루어져야 되는 상황인지, 혹은 언제든 발행된 이벤트를 읽으면 되는 상황인지에 따라 선택이 달라질 것이다.

2. 한 이벤트를 받을 수 있는 Subscriber(Consumer) 개수

한 이벤트에 대해 한 번의 기능만 작동되어야 한다면 Kafka를 사용하는 것이 유리하다.
발행된 이벤트에 대해, 특정 작업이 한 번만 발생하여야 하는지, 모든 Subscriber에서 발생되어야 하는지에 따라 다른 선택을 해야 한다.

3. RabbitMQ

AMQP 프로토콜을 구현한 메세지 브로커이다.

AMQP(Advanced Message Queuing Protocol)?

: 메세지 지향 미들웨어를 위한 개방형 표준 응용 계층 프로토콜

: Client와 Middleware broker간의 메시지를 주고받기 위한 프로토콜

  • 구성 요소
    • producer: 메세지를 보냄
    • exchange: 메세지를 목적지(큐)에 맞게 전달
    • queue: 메세지를 쌓아둠
    • consumer: 메세지를 받음
  • 메세지 처리 과정
    1. Producer 가 Broker로 메세지를 보냄
    2. Broker 내 Exchange(메세지 교환기) 에서 해당하는 key에 맞게 큐에 분배한다. (Binding or Routing 이라고 함)
      • topic 모드 : Routing Key가 정확히 일치하는 Queue에 메세지 전송 (Unicast)
      • direct 모드 : Routing Key 패턴이 일치하는 Queue에 메세지 전송 (Multicast)
      • headers 모드 : [Key:Value] 로 이루어진 header값을 기준으로 일치하는 Queue에 메세지 전송 (Multicast)
      • fanout 모드 : 해당 Exchange에 등록도니 모든 Queue에 메세지 전송 (Broadcast)
    3. 해당 큐에서 Consumer가 메세지를 받는다.
  • 장점
    • Broker 중심적인 형태로 publisher와 consumer 간의 보장되는 메세지 전달에 초점을 맞추고, 복잡한 라우팅 지원
    • 클러스터 구성이 쉽고 Manage UI 가 제공되며 플러그인도 제공되어 확장성이 뛰어남
    • 20kb/sec 정도의 속도
    • 데이터 처리 보단, 관리적 측면이다 다양한 기능 구현을 위한 서비스를 구축할 때 사용
  • 단점
    • MQ Server가 종류 후 재기동되면 기본적으로 Queue 내용은 모두 제거된다. (데이터 손실의 위험성)
    • 성능 문제
    • Producer와 Consumer 간의 결합도가 높다

사용 구분

  • 대용량 데이터 처리, 실시간, 고성능, 고가용성이 필요한 경우, 또는 저장된 이벤트를 기반으로 로그를 추적하고 재처리 하는게 필요한 경우 kafka를 쓰자.
  • 복잡한 라우팅을 유연하게 처리해야하고, 정확한 요청-응답이 필요한 Application을 쓸 때 또는 트래픽은 작지만 장시간 실행되고 안정적인 백그라운드 작업이 필요한 경우 RabbitMQ를 쓰자.
  • 이벤트 데이터를 DB에 저장하기 때문에 굳이 미들웨어에 이벤트를 저장할 필요가 없는 경우, consumer에게 굳이 꼭 알람이 도착해야한다는 보장 없이 알람처럼 push 보내는것만 중요하다면 유지보수가 편한 Redis를 사용하자.

https://velog.io/@holicme7/Apache-Kafka-카프카란-무엇인가#메세지-브로커--이벤트-브로커
https://ittrue.tistory.com/317
https://hudi.blog/what-is-kafka/
https://engineering.linecorp.com/ko/blog/how-to-use-kafka-in-line-1
https://velog.io/@courage331/Kafka-Partition%EA%B3%BC-Consumer%EC%9D%98-%EA%B4%80%EA%B3%84
https://velog.io/@hyeseong-dev/FastAPI-%EC%8B%9C%EC%9E%91%ED%95%98%EA%B8%B0#celery-%EA%B5%AC%EC%84%B1%ED%95%98%EA%B8%B0

profile
기록용

0개의 댓글