Redis, RabbitMQ, Kafka의 차이점에 대해서 필요성을 느껴 정리하려고 한다.
여러 메시지 시스템 중 Redis를 썼으나, 다른 메시지 시스템과의 차이점을 제대로 알고있지 못하기 때문이다. 이 세가지 메시지 시스템의 차이를 간략하게 한번 짚고 넘어가야겠다.
여러 메시지 플랫폼 중 이 세가지를 선택한 이유 또한 단순하다. 가장 많이 쓰이는 메시지 브로커이기 때문이다.
위 3가지 기술과 같은 메시지 기반 전달 기술들을 메시지 플랫폼이라고 부르며, 메시지 플랫폼은 아래와 같이 크게 2가지 종류로 나눌 수있다.
메시지 브로커
이벤트 브로커
그리고 이 둘은 상관 관계가 있다.
메시지 브로커는 이벤트 브로커의 역할을 할 수없지만, 이벤트 브로커는 메시지 브로커의 역할을 수행할 수있는 관계이다.
redis, rabbitmq는 메시지 브로커이고, 카프카는 이벤트 브로커이다.
메시지 브로커는 대규모 메시지 기반 미들웨어 아키텍처에서 사용된다.
미들웨어란? 애플리케이션과 이들이 동작하는 인프라 간의 효율적인 연결을 위해 존재하는 소프트웨어를 말한다.
메시지 브로커는 아래와 같은 특징을 가진다.
메시지를 받아서 적절히 처리하면 짧은 시간 내에 메시지가 삭제되는 특징을 가지고 있다.
데이터 손실의 위험을 가지고 있다.
이벤트 브로커는 이벤트 또는 메시지라고 불리는 정보를 '하나만' 보관하고 '인덱스'를 통해 개별 액세스를 관리한다.
이벤트 브로커는 아래와 같은 특징들을 가진다.
메시지 브로커와 다르게 이벤트가 삭제되지 않는다는 특징을 가진다.
서비스에서 발생하는 이벤트를 DB에 저장하듯이 이벤트 브로커의 큐에 저장한다.
이벤트를 저장하면 아래와 같은 장점들을 얻을 수있다.
장애가 발생했을때 장애가 일어난 지점부터 재처리할 수있다.
많은 양의 실시간 스트림 데이터를 효과적으로 처리할 수있다.
딱 한번 일어난 이벤트 데이터를 브로커에 저장함으로써 모든 데이터 요소를 한 곳에서만 제어 또는 편집하도록 조직하는 관례에 맞게 동작한다.
Redis에서 제공하는 메시지 브로커인 Pub/Sub 모델의 구조는 위의 그림과 같이 매우 간단하다.
이벤트를 발행하는 Publisher가 존재하고, Publisher는 특정 Channel(Topic)에 이벤트를 전송한다.
특정 Channel(Topic)을 구독하는 Subscriber가 존재하고, Publisher에 관계없이 발행된 모든 이벤트를 받을 수있다.
Redis는 RabbitMQ나 Kafka와 같은 메시징 시스템의 pub/sub 처럼 고도화된 기능을 제공하지는 않지만 In-MemoryDB의 특성을 살려 단순하지만 가볍고 빠른 pub/sub 기능을 제공한다.
Redis의 Channel은 이벤트를 저장하지 않는다는 특징을 가지고 있다. 만약 Channel에 이벤트가 도착했을때, 해당 채널의 Subscriber가 존재하지 않는다면, 이벤트는 자연스럽게 사라진다.
Subscriber는 동시에 여러 Channel을 구독할 수있으며, 특정한 채널 이름을 명명하지 않고 '패턴'으로도 채널을 구독할 수있다.
Redis의 pub/sub system을 뜯어보면 메시지가 발행될때 독특하다.
subscriber는 계속 channel을 listen 하고있지 않다. publish 되면 메시지 브로커가 구독하고 있는 client 들에게 message를 publish 하는 식의 구조이다.
Redis는 메모리 내에 데이터를 저장하기 때문에 지속성이 필요하지 않은 단기 메시지가 있을때 적합하다. 매우 빠른 서비스와 메모리내 데이터로 인해 지속성이 중요하지 않고 어느정도 손실을 처리할 수있는 짧은 보존 메시지에 적합하다.
RabbitMQ도 서버간 메시지를 전달해주는 오픈소스 메시지 브로커이다. 메시지 큐잉 / pub sub을 모두 사용할 수있다.
예를들어 A -> B 서버로 메시지를 전달하려고 한다. 이때 이 중간에서 메시지를 받고, 전달해주는 역할을 한다.
동작하는 구조는 아래와 같다.
RabbitMQ의 구성요소로는 총 4가지가 존재한다.
Producer : 메시지를 보낸다.
Exchange : 메시지를 목적지 큐에 맞게 전달한다.
Queue : 메시지를 저장한다.
Consumer : 메시지를 받아 사용한다.
메시지 처리 과정은 아래와 같다.
Producer가 메시지를 보낸다.
Exchange에서 해당하는 키에 맞게 큐에 바인딩한다.
해당 큐를 사용하는 Consumer가 메시지를 받는다.
RabbitMQ의 가장 큰 특징은 메시지 라우팅 키를 통해 메시지 라우팅을 지원하는 점이다. 별도의 미들웨어가 필요하지 않고 토픽 대신 Exchange와 Queue의 바인딩을 통해 메시지를 소비할 수있다.
RabbitMQ는 지정된 Consumer에게 원하는 방식으로 메시징을 신뢰성있게 전달하는데 초점이 맞춰져 있다. 또한 빠르게 쉽게 구성할 수있으며 직관적이다. 라우팅도 매우 유연하다는 특징을 가지고 있다.
RabbitMQ는 많은 기능을 가지고 있는 메시지 브로커로 복잡한 라우팅이 필요할때 선택하면 좋은 선택지이다.
Kafka는 pub/sub system model과 MQ를 혼합해서 사용하는 이벤트 브로커이다.
pub/sub model은 비동기 메시징 전송 방식이다.
발신자의 메시지는 수신자가 정해져 있지 않는 상태로 publish 된다. 그리고 이 publish 된 메시지는 subscribe한 사용자가 받는다.
pub/sub system에서 수신자는 발신자의 정보가 없어도 메시지를 수신할 수있고, 이러한 구조 때문에 높은 확장성을 가질 수있다.
pub/sub 통신 방법을 사용하지 않으면 일반적으로 직접 연결하여 통신한다. 이럴경우 빠른 전송 속도와 전송 결과를 신속하게 알 수있다는 장점이 존재한다. 하지만 여기서 큰 문제는 특정 서비스에 장애가 발생할 경우 메시지를 보내는 쪽에서 대기 처리 등을 개별적으로 처리하지 않으면 시스템에 문제가 발생한다는 것이다.
한마디로 시스템이 커지면서 확장성이 떨어진다는 것을 말한다.
하지만, pub/sub 모델은 단점도 존재한다. 각 서버가 직접 통신을 하지 않기 때문에 메시지가 정확하게 전달되었는지 확인하는 과정이 복잡하고, 중간에 메시징 시스템이 있기 때문에 메시지 전달 속도가 빠르지 않다는 점이다. 그래서 pub/sub 모델은 대규모 데이터를 전달하기보다는 간단한 데이터를 전송하는데 주로 사용되었으며, 큰 데이터를 처리하는 조직이나 회사의 경우 성능이 문제가 되었다.
카프카는 일반적인 pub/sub model에서 언급되는 문제점인 메시지가 정확하게 전달되었는지 확인하는 복잡한 과정을 해결하고, 메시지 전달 속도를 향상시켰다.
메시지 전달의 신뢰성 관리를 producer와 consumer 쪽으로 넘기고, 부하가 많이 걸리는 메시지 교환기 기능 역시 consumer가 만들 수있게 함으로써 메시징 시스템 내에서의 작업량을 줄이고 이렇게 절약한 작업량을 메시징 전달 성능에 집중시켜서 고성능 메시징 시스템을 만들었다.
카프카 공식문서를 보면 위와같은 아키텍처로 구성되어 있다.
카프카 클러스터를 중심으로 producer와 consumer가 데이터를 push하고 pull하는 구조이다.
이때 Producer와 consumer는 각각 다른 프로세스에서 비동기로 작동하고 있다.
카프카가 사용되기 적절한 상황은 대규모 트래픽이 예상되고, 많은 확장이 예상될때 어울린다.
분명 틀린 내용이 있을 것이고, 사용해보지 않은 영역이라 어렵다.
메모리 기반 데이터 관리 시스템이다.
처리 속도가 빠르며, 서버가 다운되면 redis 내의 모든 데이터가 사라진다.
가볍고 빠르다는 특징이 있고, publish 된 메시지들을 저장하지 않는다는 특징을 가진다.
구성이 쉽다.
복잡한 라우팅을 지원한다.
소비자 중심의 설계이다.
데이터 손실의 위험성이 있다.
pub/sub 방식의 비동기식 구성이다
분산 처리에 효과적이다.
생산자 중심의 설계방식이다.
이벤트 기반 서비스 아키텍처에 적합하고, 확장이 쉽다.