MSA와 Redis

SummerToday·2025년 1월 6일
0
post-thumbnail

NoSQL의 등장 배경

올바른 데이터 저장소를 선택하고 운영하는 것은 애플리케이션의 성능과 확장성, 가용성과 신뢰성 등 여러 문제와 직접적인 연관을 갖는다.

모놀리틱 아키텍처

  • 전체 애플리케션을 하나의 통합된 패키지로 개발, 배포하는 방식.

    • 즉, 모든 시스템은 하나로 연결돼 관리된다.
  • 소규모 프로젝트 같은 경우에는 모놀리틱 구조가 운영하기 쉽지만, 서비스의 규모가 확장되면 유지보수의 복잡도도 증가된다는 단점이 존재.

    • 한 개의 시스템에 문제가 발생하면, 전체 시스템의 장애로 이어진다.
  • 모듈간 의존성이 높다.

    • 하나의 모듈을 수정하면 전체 애플리케이션을 다시 배포해야 한다.
  • 하나의 파트에서 리소스가 모자라서 그 부분만 확장을 시키고 싶어도 전체를 확장시켜야 한다.

    • 리소스 낭비의 문제가 발생할 수 있다.

마이크로서비스 아키텍처(MSA)

출처: https://www.f5.com/company/blog/nginx/introduction-to-microservices

  • MSA는 독립된 각각의 모듈을 조립해 하나의 서비스를 만드는 아키텍처이다.

  • 기능별로 작게 나뉘어진 서비스가 독립적으로 동작하는 서비스를 의미한다.

    • 업데이트, 테스트, 배포, 확장은 각 서비스 별로 독립적으로 수행될 수 있다.
  • 모듈간 의존성이 낮다. -> 운영 안정성이 향상된다.

  • 하지만, 개발 및 운영에 있어 인원이 충분하지 않는 소규모 팀에서는 서비스 분리로 인한 관리 복잡도와 운영 부담이 증가되는 단점이 존재한다.


데이터 저장소 요구 사항의 변화

  • RDBMS 같은 경우에는 고정된 스키마를 가지고 있고, 테이블 간의 관계를 정확하게 규정하고 있다.

    • 서비스의 규모가 커질수록 데이터를 추출하기 위한 쿼리가 복잡해진다.

    • 관계 간의 복잡성 문제로 쿼리 성능에 이슈가 발생하며, 쿼리 성능을 향상 시키기 위해 쿼리, 인덱스, 테이블 구조를 자주 최적화 해야한다.

  • RDMS를 통해 데이터의 집약화를 이뤄 서비스를 구축하는 경우에는 RDBMS의 주기적인 최적화가 서비스 성능에 큰 영향을 미쳤다.

    RDMS의 특성: ACID

    • 원자성(Atomicity): 트랜잭션이 완벽하게 실행되거나 아예 실행되지 않음을 보장한다.
    • 일관성(Consistency): 트랜잭션은 실행 전후로도 제약 조건을 만족시킴을 보장한다.
    • 독립성(Isolation): 트랜잭션 실행 시 다른 트랜잭션의 개입이 없음을 보장한다.
    • 지속성(Durability): 성공적으로 수행된 트랜잭션은 영원히 반영돼야 함을 보장한다.
  • 하지만, 다차원 적이고 깊은 계층 구조를 가지는 비정형 데이터는 RDBMS의 정형화된 테이블에서는 관리가 힘들다.

  • 실시간 로그 데이터와 같은 시계열 데이터들은 RDBMS에 저장하는 것이 쉽지 않다.

  • RDBMS를 사용하는 경우에는 테이블 구조 변경을 위해 DA가 승인하고, DBA가 작업을 진행하기에 개발 속도가 저하될 수 있다.

    • NoSQL 사용 시 개발 팀이 바로 데이터 구조를 바꿀 수 있어 더 빠른 개발이 가능하다.

    • 비즈니스의 특성과 데이터의 형태를 고려하여 NoSQL과 RDBMS를 적절히 선택해 운영해야 한다.

  • MSA에서 가장 중요한 것은 서비스는 스스로의 상태를 유지하고, 이를 위해 독립된 데이터 저장소가 필요하다.


NoSQL이란?

  • Not Only SQL을 의미한다.

  • 관계형 데이터베이스에서 테이블의 데이터를 쿼리하기 위한 SQL(Standard Query Language)을 사용하지 않는 데이터 저장소임을 의미한다.


실시간 응답

  • 데이터 저장소에서 데이터를 가져올 때 발생할 수 있는 지연은 0 ~ 1ms 이내여야 한다.

  • MSA에서 개별 서비스가 빠르게 동작하지 않을 때, 서비스 자체가 병목 현상을 유발할 수 있다.


확장성

  • 예상치 못한 이벤트로 인한 트랜잭션의 증가에 수평적 확장 등으로 유연하게 확장될 수 있다.

고가용성

  • NoSQL은 분산 시스템 기반으로 데이터를 여러 노드에 복제하고 샤딩하여, 일부 노드가 장애를 겪어도 서비스가 중단되지 않도록 고가용성을 보장한다.

  • 자동 장애 복구와 무중단 유지보수를 지원해 안정적인 데이터 접근이 가능하다.


클라우드 네이티브

  • NoSQL은 분산 아키텍처와 스키마리스 구조로 클라우드의 수평적 확장성과 자원 유연성에 최적화되어 있다.

  • 자동 복구와 데이터 복제를 통해 클라우드 환경에서 고가용성과 확장성을 쉽게 구현할 수 있다


단순성

  • 개발자와 운영자가 데이터 저장소를 간단하게 사용할 수 있다.

  • NoSQL이 스키마리스 구조를 제공해 데이터 모델 변경이 자유롭고, 복잡한 설정 없이 자동 복제와 확장이 가능하기 때문이다.


유연성

  • NoSQL은 관계형 데이터보다 다양한 방식으로 비정형 데이터를 저장할 수 있는 방법을 제공한다.

NoSQL 데이터 저장소 유형

출처: https://www.linkedin.com/pulse/nosql-databases-empowering-modern-data-management-jagarlapoodi/

  • NoSQL은 그래프, 칼럼, 문서, 키-값 유형으로 다양한 방식으로 데이터를 저장한다.

그래프 유형

출처: https://singhnaveen.medium.com/what-are-graph-databases-and-different-types-of-graph-databases-369e5040a9d0

  • 엔티티 간의 관계를 효율적으로 저장하도록 설계됐다.

  • 노드(Node), 엣지(Edges), 속성(properties)으로 데이터를 나타내고, 데이터의 엔티티는 노드로 표현하며, 데이터 사이의 관계를 엣지로 나타낸다.

    • 에지는 항상 시작 노드, 끝 노드, 유형과 방향을 가지며 상-하위 관계, 동작, 소유자 등의 정보를 저장한다.
  • 데이터 간 관계를 저장하고 표현할 때 유용하며 저장되는 속성의 크가 크거나 매우 많은 경우에는 적합하지 않다.

  • 친구 관계를 이용한 추천 서비스에서 유용하게 사용될 수 있다.


칼럼 유형

출처: https://www.techtarget.com/searchdatamanagement/tip/NoSQL-database-types-explained-Column-oriented-databases

  • 데이터를 행(Row)이 아닌 열(Column)을 기준으로 저장한다.

  • 칼럼 유형은 칼럼 지향적(column-oriented) 또는 와이드 칼럼(wide column) 유형으로도 불린다.

  • 대량의 데이터에 대한 집계 쿼리를 다른 유형보다 훨씬 빠르게 처리할 수 있다.

    • 분석, 보고, 빅데이터 처리에 적합하며 대표적인 DB로는 Apache Cassandra, HBase 등이 존재한다.

문서 유형

출처: https://lennilobel.wordpress.com/2015/06/01/relational-databases-vs-nosql-document-databases/

  • JSON 형태로 데이터가 저장돼, 개발자들이 편하게 사용할 수 있다.

  • 스키마가 따로 정해져 있지 않아, 애플리케이션에 맞게 데이터를 그대로 저장할 수 있어 유연성이 크다.

  • 데이터를 저장하거나 검색하는 데 효과적이며 MongoDB, CouchDB, AWS DocumentDB 등이 존재한다.


키-값 유형

출처: https://www.researchgate.net/figure/Key-value-NoSQL-Database_fig1_332188615

  • 가장 단순하여 빠른 데이터 액세스와 처리 속도를 보장한다.

  • 데이터의 저장이 간단하기 때문에 다른 유형보다 수평적 확장이 쉽다.

  • 게임, IoT와 같은 로그를 남기는 작업이나 대규모 세션을 실시간으로 관리하는 상황에서 유용하다.

  • AWS Elasticache, AWS DynamoDB, Oracle NoSQL Database, Memcached 등이 존재한다.


레디스란?

  • Remote dictionary server(Redis)의 약자이다.

  • 고성능 키-값 유형의 인메모리(in-memory) NoSQL 데이터베이스로, 오픈 소스 기반의 데이터 저장소이다.

    인메모리(In-Memory)는 데이터를 디스크가 아닌 RAM에 저장하여 빠르게 읽고 쓰는 방식을 의미한다.
    이 방식은 지연 시간(Latency)을 최소화하고, 실시간 데이터 처리나 캐싱, 세션 관리 등에 유리하다.


레디스의 특징

  • 실시간 응답(빠른 성능)

    • 인메모리 형태의 데이터베이스에서는 모든 데이터가 컴퓨터의 메모리에서 관리되기에 데이터의 처리 성능이 굉장히 빠르다.

  • 단순성

    • 키에 매핑되는 값에는 문자열, 해시(hash), 셋(set) 등 복잡하고 다양한 데이터 구조를 저장할 수 있다.

    • 내장된 다양한 자료 구조를 통해 임피던스 불일치를 해소하고 개발을 편리하게 할 수 있다.

      • 기존 관계형 데이터베이스의 테이블과 프로그래밍 언어 간 데이터 구조, 기능의 차이로 인해 발생하는 충돌을 의미한다.
    • 다양한 오픈 소스 클라이언트를 사용할 수 있으며, 다양한 개발 언어를 지원한다.

    • 레디스는 싱글 스레드로 동작한다.

      출처: https://blog.devgenius.io/lets-dance-on-the-redis-floor-d93e02828bef

      • 메인 스레드 1개와 별도의 스레드 3개 총 4개의 스레드로 동작한다.

      • 하지만 클라이언트의 커맨드를 처리하는 부분은 이벤트 루프를 이용한 싱글 스레드로 동작한다.

        • 하나의 쿼리가 완료 될 때까지 다른 쿼리들은 대기를 하고, 반환이 느린 특정 커맨드들을 사용할 시 장애가 발생할 확률이 매매우 높아지기 때문에 주의해야한다.

  • 고가용성

    • 레디스는 자체적으로 HA(High Availability) 기능을 제공한다.

      • 복제를 통해 여러 서버에 데이터 분산이 가능하다.

      • 센티널(sentinel)은 장애 상황을 탐지해 자동으로 페일오버(failover)를 시켜준다.

      • 애플리케이션 - 센티넬 - 레디스 구조에서는 마스터에 장애가 발생해도 레디스 엔드포인트를 변경하지 않아도 페일오버가 자동으로 이루어져 정상화된 마스터 노드를 사용할 수 있다.


  • 확장성

    출처: https://www.aeraki.net/docs/v1.x/tutorials/redis/cluster/

    • 클러스터 모드를 이용해 쉽게 수평적 확장을 할 수 있다.

    • 데이터는 레디스 클러스터 내에서 자동으로 샤딩된 후 저장된다.

    • 클러스터 구조에서 모든 레디스 인스턴스는 클러스터 버스라는 프로토콜을 이용해 서로 감시를 하여 마스터 노드에 장애가 발생할 시 자동으로 페일오버를 시켜준다.


  • 클라우드 네이티브

    • 클라우드 네이티브는 클라우드 환경에 특화된 애플리케이션의 개발 및 운영 방식을 의미한다.

      • 빠른 배포와 확장성, 높은 복원력을 중심으로 한 애플리케이션을 추구한다.
    • 레디스는 멀티 클라우드 환경에서 일관된 성능과 기능을 제공하여 서비스의 연속성과 데이터의 일관성을 보장한다.


마이크로서비스 아키텍처와 레디스

데이터 저장소로서의 레디스

  • 각 서비스별 개별 저장소로 사용하기에 간편하다.

    • 최소한의 리소스로 막대한 처리량을 제공하며 다양한 자료 구조를 제공하면서 사용이 간단하기 때문.
  • 고가용성을 위해 로드 밸런서나 프록시 등 추가적인 서비스를 설치할 필요가 없다.

  • 데이터의 영속성을 위해 AOF(Append Only File)와 RDB(Redis DataBase)형식으로 디스크에 주기적으로 저장할 수 있다.

  • 장애가 발생해 데이터가 유실되도 백업 파일을 이용하면 쉽게 복구가 가능하다.


메시지 브로커로서의 레디스

  • MSA에서는 서비스들 간 지속적 통신을 위해 메시징 큐 혹은 steam과 같은 메시지 브로커를 이용해 서비스들 간에 비동기 통신 채널을 구현하는 것이 좋다.

  • Redis pub/sub 기능을 통해 메시징 기능을 구현할 수 있다.

    • 1개의 채널에 데이터를 던지면 해당 채널을 듣고 있는 모든 소비자는 데이터를 빠르게 가져올 수 있다.

    • 하지만 모든 데이터는 전달된 뒤 삭제되므로 fire-and-forgot 패턴이 필요한 간단한 알림 서비스에서 유용하다.

    • list 자료 구조를 이용하여 메시징 큐로 사용하고, 블로킹 기능도 사용할 수 있다.

      • 킹 기능
        redis 블로킹 기능은 특정 명령어를 실행할 때, 조건이 충족될 때까지 클라이언트를 대기 상태로 유지하는 기능이다. 이 기능은 주로 리스트(List) 자료구조에서 사용되며, 데이터를 기다리는 상황에서 유용하다.
  • stream 자료 구조를 이용하여 스트림 플랫폼으로 사용할 수 있다.

    • stream 자료 구조는 테이터는 계속해서 추가되는 방식으로 저장된다.

    • 카프카처럼 저장되는 데이터를 읽을 수 있는 소비자와 소비자 그룹이 존재해 데이터의 분산 처리가 가능하고 시간대별로 검색도 가능하다.




해당 글은 다음 도서의 내용을 정리하고 참고한 글임을 밝힙니다. 보다 자세한 내용은 아래 책에서 확인할 수 있습니다. 김가림, ⌜개발자를 위한 레디스⌟, 에이콘출판, 2023, 432쪽
profile
블로그 이관했습니다.

0개의 댓글