본문 바로가기

개발자를 위한 레디스

[개발자를 위한 레디스] 레디스를 메시지 브로커로 사용하기


1) 메시지 브로커의 필요성 

 

- 최근의 서비스 아키텍처는 여러 모듈이 서로 느슨하고 적절하게 연결시킨 구조를 선호하고 있다.

  이런 형태의 구조는 다양한 장점을 갖고 있지만

  모듈 간 서로 탄탄한 상호 작용이 필요하기 때문에

  효율적인 메시징 솔루션, 즉 메시지 브로커를 필요로 한다.

 

- 서비스 간 커넥션이 실패하는 상황은 언제나 발생할 수 있다.

  서비스 배포처럼 예정된 작업 도중 발생할 수도 있지만,

  예기치 못한 장애로 인해 통신이 안 될 상황도 고려해야 한다.

 

- 따라서 모듈 간의 통신에서는 되도록 비동기 통신을 사용하는 것을 권장하며,

  동기 통신의 횟수를 최대한 줄이는 것이 바람직하다.

 

- 서비스 간 통신이 불가능한 상황이 바로 장애로 이어지지 않게,

   당장 메시지를 처리하지 못하더라도 보낸 메시지를 어딘가에 쌓아 둔 뒤

   나중에 처리할 수 있는 채널을 만들어 주는 것. 이것이 메시지 브로커의 핵심 역할이라 할 수 있다. 

 

 

2) 메시지 브로커의 두 가지 형태 - 메시징 큐 vs 이벤트 스트림  

- 메시지 브로커는 크게 메시징 큐와 이벤트 스트림이라는 두 가지 형태로 나눌 수 있다.

  우선 두 가지 방식의 차이에 대해서 알아보자. 

 

 

 

- 메시징 큐에서는 주로 데이터를 생성하는 쪽을 생산자(producer), 데이터를 수신하는 쪽을 소비자(consumer)로 지칭한다.

 

- 이와 유사하게, 이벤트 스트림에서는

  데이터를 생성하는 쪽을 발행자(publisher)로 데이터를 조회하는 쪽을 구독자(subscriber)로 지칭한다.

  이 용어들은 자주 혼용된다.

 

 

(1) 메시징 큐와 이벤트 스트림의 두 가지 차이점

 

- 메시징 큐와 이벤트 스트림은 크게 두 가지 차이점을 갖고 있다.

 

(1-1) 방향성

-  메시징 큐의 생산자는 소비자의 큐로 데이터를 직접 푸시한다.

   2개의 서비스에 같은 메시지를 보내야 할 때 메시징 큐를 이용한다면

  생산자는 2개의 각각 다른 메시징 큐에 각각 데이터를 푸시(push)해야 한다.

 

- 반면, 스트림을 이용한다면 생산자는 스트림의 특정 저장소에 하나의 메시지를 보낼 

  수 있고, 메시지를 읽어가고자 하는 소비자들은 스트림에서 같은 메시지를 풀(pull)해 갈 수 있기 때문에

  메시지를 복제해서 저장하지 않아도 된다. 

 

 

(1-2) 데이터의 영속성

- 메시징 큐에서는 소비자가 데이터를 읽어갈 때 큐에서 데이터를 삭제한다.

  하지만 이벤트 스트림에서 구독자가 읽어간 데이터는 바로 삭제되지 않고,

  저장소의 설정에 따라 특정 기간 동안 저장될 수 있다.

  

- 메시지를 보내는 도중에 새로운 소비자를 추가할 때, 메시징 큐를 이용한다면

   소비자는 새롭게 추가된 이후의 이벤트만 확인할 수 있다. 

 

 

 

3) 레디스를 메시지 브로커로 사용하기

 

(1) Redis Pub/Sub

 

-레디스에서 제공하는 pub/sub을 사용하면 빠르고 간단한 방식으로

  메시지를 전달할 수 있는 메시지 브로커를 구현할 수 있다.

 

- 발행자가 특정한 채널에 데이터를 전송하면 이 채널을 듣고 있는 모든 소비자는 데이터를 바로 소비할 수 있다.

 레디스의 pub/sub에서 모든 데이터는 한 번 채널 전체에 전파된 뒤 삭제되는 일회성의 특징을 가지며,

 메시지가 잘 전달됐는지 등의 정보는 보장하지 않는다.

 

- 따라서 완벽하게 메시지가 전달돼야 하는 상황에는 적합하지 않을 수 있지만,

  fire-and-forget 패턴이 필요한 간단한 알림(notification) 서비스에서는 유용하게 사용될 수 있다. 

 

- 레디스의 list 자료 구조는 메시징 큐로 사용하기에 알맞다.

   list의 데이터는 푸시와 팝이 가능하며 애플리케이션은 list에 데이터가 있는지

   매번 확인할 필요 없이 대기하다가 list에 새로운 데이터가 들어오면 읽어갈 수 있는 블로킹 기능을 사용할 수도 있다. 

 

 

(2) Redis Stream

 

- 레디스의 stream을 사용하면 레디스를 완벽한 스트림 플랫폼으로 사용할 수 있다.

  레디스 stream은 아파치 카프카 시스템에서 영감을 받아 만들어진 자료 구조로,

  데이터는 계속해서 추가되는 방식으로 저장된다(append-only)

 

-  소비자와 소비자 그룹이라는 개념을 이용하면

   카프카에서와 비슷하게 데이터의 분산 처리를 구현할 수 있다.

  s tream에 저장되는 메시지를 실시간으로 리스닝하며 소비할 수도 있으며,

  저장돼 있는 데이터를 시간대별로 검색하는 것도 가능하다.