Using Redis as a Message Broker

최근의 서비스 아키텍처 → 여러 모듈들의 Loose Coupling 선호 → 모듈간 탄탄한 상호 작용 필요 → 효율적인 메시징 솔루션(메시지 브로커) 필요성

  • 예기치 못한 장애 → 통신이 안되는 상황 고려 필요
    • 비동기(async) 통신 사용 권장
    • 동기(sync) 통신 횟수를 줄이는 것이 바람직
  • 서비스 간 통신이 불가능한 상황이 바로 장애로 이어지지 않도록, 보낸 메시지를 쌓아 둔 뒤 나중에 처리할 수 있는 채널이 필요함
    • 메시지 브로커의 역할

Message Queue and Event Stream

  • Message Queue
    • 생산자(producer): 데이터를 생성하는 쪽
    • 소비자(consumer): 데이터를 수신하는 쪽
  • 이벤트 스트림(Event Stream)
    • 발행자(publisher): 데이터를 생성하는 쪽
    • 구독자(subscriber): 데이터를 조회하는 쪽
  • 주요 차이점
    • 방향성
      • 메시지 큐의 생산자는 소비자의 큐로 데이터를 직접 Push
        • e.g) 2개의 서비스에 같은 메시지를 보내야할 때 메시징 큐에서는 각각 다른 메시징 큐에 각각 데이터를 Push
      • 이벤트 스트림의 생산자는 스트림의 특정 저장소에 하나의 메시지를 보낼 수 있고, 메시지를 읽어가고자 하는 소비자들은 스트림에서 같은 메시지를 Pull해 갈 수 있다.
    • 데이터의 영속성
      • 메시지 큐에서는 소비자가 데이터를 읽어가면 큐에서 데이터를 삭제
        • e.g) 메시지를 보내는 도중, 새로운 소비자가 추가된다면 소비자는 새롭게 추가된 이후의 이벤트만 확인 가능
      • 이벤트 스트림에서는 바로 삭제되지 않고, 설정에 따라 특정 기간 동안 저장될 수 있음
        • e.g) 스트림에 쌓인 데이터는 일정 기간 동안 지워지지 않기 때문에 새로 추가된 서비스도 스트림에 남아있는 이전 데이터의 히스토리를 볼 수 있음
  • 메시지 큐는 일대일(1:1) 상황에서 유용하게 사용
  • 스트림은 다대다(n:n) 상황에서 유리함

Redis pub/sub

레디스는 아주 가벼운 pub/sub 기능 제공

  • publisher →(pub)→ 메시지 → [ 특정 Channel ] →(sub)→ 메시지 → subscriber
  • 매우 가벼움최소한의 메시지 전달 기능만 제공
    • 발행자: 메시지를 채널로 보낼 수만 있다.
    • 구독자: 메시지를 받을 수 만 있다.
    • e.g) 모든 구독자에게 메시지가 전달됐는지와 같은 기능 제공하지 않음
  • 한 번 전파된 메시지는 레디스에 저장되지 않음
  • 단순한 메시지 통로 역할
  • 장애가 발생해 메시지를 받지 못하더라도, 사실을 알 수 없다.
    • 정합성이 중요한 데이터 전달에는 적합하지 않을 수 있음
  • 메시지 publish하기

      PUBLISH hello world
      (integer) 0
    
  • 메시지 구독(subscribe)하기
    • e.g) event1, event2 채널을 동시 구독
      SUBSCRIBE event1 event2
      1) "subscribe"
      2) "event1"
      3) (integer) 1
      1) "subscribe"
      2) "event2"
      3) (integer) 2
    
    • PSUBSCRIBE 일치하는 패턴에 해당하는 채널을 한 번에 구독(glob-style pattern)
      • 메시지는 pmessage 타입으로 전달
      • SUBSCRIBE 커맨드를 이용해 구독하는 방식과 구분됨
      PSUBSCRIBE mail-*
      1) "psubscribe"
      2) "mail-*"
      3) (integer) 1