Redis

[Redis] Redis Streams

꾸준함. 2023. 11. 22. 16:52

개요

MSA(Micro Service Architecture)를 적용한 프로젝트 내 각 모듈들은 확실히 분리되고 독립성을 가지는 것이 가장 중요합니다.

이 때문에 각 서비스들은 별도 독립된 DB를 가진 상태로 상호 간 API를 이용해 통신하는 케이스가 많습니다.

이런 구조는 모듈끼리 결합도가 강해지는 단점이 있는데 Event-Driven 아키텍처를 적용하면서 이벤트 생산자/소비자 간 결합도를 낮추는 장점을 취할 수 있습니다.

이번 게시글에서는 MSA 개념을 간단히 복습 후 Event-Driven 아키텍처의 장단점 및 해당 아키텍처를 적용한 Redis Streams를 다루겠습니다.

 

MSA

MSA는 아래의 특성을 가집니다.

  • 시스템을 독립적인 단위의 작은 서비스들로 분리
  • 각 서비스들은 별도 DB를 가지고 다른 서비스의 DB 접근 불가
  • 각 서비스들은 API를 통해서만 통신

 

MSA를 이상적으로 도입했을 때 장단점은 아래와 같습니다. (이상과 현실은 많이 다르다는 것을 개발 연차가 쌓이면서 깨닫고 있습니다..)

 

장점

  • 높은 응집도, 낮은 결합도
  • 서비스 별로 독립적인 개발과 배포 가능
  • 서비스 크기가 작아져 유지보수가 용이함
  • 서비스 간 결합도가 낮을 경우보다 빠른 개발, 테스트, 배포가 가능
  • 서비스 별로 개별 확장 가능
  • 적절한 fallback 처리를 했을 경우 일부 서비스 실패가 전체 시스템 실패로 이루어지지 않음

 

단점

  • 분산 시스템의 문제점을 고스란히 가져감 (부분 장애, 네트워크 실패, 데이터 동기화, 로드 밸런싱, 개발 및 관리의 복잡성)
  • 서비스들을 분리할수록 통합 테스트가 어려움
  • 서비스들이 분리되어있기 때문에 모니터링/디버깅 복잡도 증가
  • 트랜잭션 관리의 어려움
  • 서비스 간 통신 구조에 대한 고민 필요 (동기 vs 비동기, HTTP vs GRPC, 통신 브로커, etc.)

 

 

더 자세한 내용은 제가 예전에 작성한 게시글을 참고 바랍니다.

 

https://jaimemin.tistory.com/1827

 

도커와 마이크로 서비스 아키텍처 개요 (Docker & MSA)

개요 2019년에 인턴 생활을 했을 때, MSA(Micro Service Architecture)라는 키워드가 동기들 사이에서 자주 등장했었고 실제로 면접에서도 자주 등장했었던 내용이었습니다. 그리고 지금 현재 2021년에는

jaimemin.tistory.com

 

Event-Driven 아키텍처

Event-Driven 아키텍처는 이벤트의 consumer/producer 구조로 통신이 이루어지며 분산 시스템에서의 통신 방식 중 하나입니다.

MSA로 분리된 각 서비스들은 이벤트 저장소인 Event-broker와의 의존성만 가집니다.

 

https://www.scylladb.com/glossary/event-driven-architecture/

 

 

Event-Driven 아키텍처를 도입했을 때 장단점은 아래와 같습니다.

 

장점

  • 위 그림을 보면 알 수 있다시피 공통적인 Event-broker에 대한 결합만 있기 때문에 이벤트 producer/consumer 간의 결합도가 낮아짐
  • 결합도가 낮아지기 때문에 서버 추가, 삭제 시 타 서버를 변경할 필요가 적어져 유연한 변경 가능
  • 장애가 발생하더라도 이벤트는 저장되고 이후에 해소되었을 때 처리가 되기 때문에 장애 탄력성을 갖춤

 

단점

  • 모듈 간 느슨하게 연결되었기 때문에 시스템의 예측 가능성 떨어짐
  • 통합 테스트 어려움
  • 장애 추적 어려움

 

Redis Streams

Redis Streams는 append-only log를 구현한 자료구조로 하나의 key로 식별되는 하나의 stream에 엔트리가 계속 추가되는 구조입니다.

하나의 엔트리는 entry ID + (key-value 리스트)로 구성이 되며 append-only이기 때문에 추가된 데이터는 사용자가 삭제하지 않는 한 지워지지 않습니다.

  • 하나의 entry는 로그 한 줄

 

Redis Streams 활용 사례는 아래와 같으며 이 중 주로 Event-driven 아키텍처 내 이벤트 저장소로 사용이 됩니다.

  • 센서 모니터링 (지속적으로 데이터 수집)
  • 유저별 알림 데이터 저장
  • 이벤트 저장소

 

https://nimasrn.medium.com/introduction-to-redis-streams-1d6a95ab141

 

 

Redis Streams 명령어

 

XADD

  • 특정 key의 stream에 엔트리를 추가하는 명령어
  • 해당 key 내 stream이 없으면 생성

 

ex) user-notifications라는 stream에 1개의 엔트리를 추가하여 3개의 field-value 쌍을 넣는 케이스

 

XADD user-notifications * message1 hi message2 hello message3 greetings

 

XRANGE

  • 특정 ID 범위의 엔트리를 반환

 

ex) user-notifications의 모든 범위 조회

 

XRANGE user-notifications - +

 

 

XREAD

  • 한 개 이상의 key에 대해 특정 ID 이후의 엔트리 반환
  • 명령어 내 BLOCK 포함 시 동기, 미포함 시 비동기 방식으로 진행

 

ex) user-notifications의 0보다 큰 ID 조회 (동기)

 

XREAD BLOCK 0 STREAMS user-notifications 0

 

ex) user-notifications의 0보다 큰 ID 조회 (비동기)

 

XREAD 0 STREAMS user-notifications 0

 

ex) user-notifications에서 새로 들어오는 엔트리를 동기 방식으로 조회 (event listener와 같은 방식)

 

XREAD BLOCK 0 STEAMS user-notifications $

 

XGROUP CREATE

  • 한 stream을 여러 consumer가 분산 처리할 수 있으며 하나의 그룹에 속한 consumer는 서로 다른 엔트리를 조회
  • XGROUP CREATE는 consumer group을 생성하는 명령어

 

ex) user-notifications에 consumer-group1이라는 consumer-group 생성

 

XGROUP CREATE user-notifications consumer-group1

 

XREADGROUP

  • 특정 key의 stream을 조회하는데 특정 consumer group에 속한 consumer로 읽음

 

ex) user-notifications에서 consumer-group1 그룹으로 2개의 consumer가 각각 1개씩 조회

  • 끝에 >를 붙임으로써 아직 소비되지 않은 메시지를 가져옴

 

XREADGROUP GROUP consumer-group1 consumer1 COUNT 1 STREAMS user-notifications >
XREADGROUP GROUP consumer-group1 consumer2 COUNT 1 STREAMS user-notifications >

 

 

Redis Streams 활용 예시

시스템이 주문, 결제, 알림 서비스로 분리되어있고 event-driven 아키텍처를 적용하여 각각의 모듈은 redis streams 이벤트 브로커에 대한 결합만 있다고 가정합니다.

 

전체적인 프로세스는 아래와 같이 동작할 것입니다.

  1. 클라이언트가 주문을 하여 주문 서비스에서 주문 이벤트(order-events) 생성
  2. 결제 서비스 내 이벤트 리스너가 구현되어 있어 주문 이벤트가 발생할 때마다 읽어오고 결제 처리 및 결제 완료(payment-events) 이벤트 생성
  3. 알림 서비스는 주문 이벤트가 발생할 때마다 주문 상태 알림을 클라이언트에게 발송
  4. 알림 서비스는 결제 완료 이벤트가 발생할 때마다 결제 완료 알림을 클라이언트에게 발송

 

 

참고

백엔드 개발자를 위한 한 번에 끝내는 대용량 데이터 & 트래픽 처리 초격자 패키지 Online - 고성능 서비스를 위한 Redis 활용 및 아키텍처

반응형

'Redis' 카테고리의 다른 글

[Redis] Redis 성능 튜닝  (1) 2023.11.21
[Redis] Redis 클러스터 개념 정리  (0) 2023.11.20
[Redis] Redis 백업 및 장애 복구 방법 정리  (0) 2023.11.15