[Architecture] MSA : CQRS 패턴이란

Cover image

MSA : CQRS 패턴의 정의과 종류

지난 시간에는 MSA와 MSA 패턴 중, SAGA 패턴에 대해 알아보았습니다.


CQRS 패턴이란.

CQRS 패턴이란 Command and Query Responsibility Segregation의 약자입니다. 이를 해석하면 명령과 쿼리의 역할을 구분한다는 것입니다. 즉, Command (Create, Insert, Update, Delete)와 쿼리(Select - Read)의 책임을 분리하는 의미를 가집니다.


CQRS가 왜 필요한가요?

전통적인 CRUD 아키텍처 기반에서 Application을 개발 및 운영하다가 보면, 자연스럽게 Domain Model의 복잡도가 증가하고 그에 따라 유지보수의 비용이 증가하고 Domain model은 설계의 방향과 다르게 변질됩니다. 특히 요즘처럼 고급화된 UX, 어려워진 Business, 자주 변하는 요구사항에서 이러한 Model을 설계하는 것은 어려워졌습니다.

이러한 흐름에서 확인해보니, 대부분의 정책이나 제약은 데이터 변경(C, U, D)에서 처리되고, 데이터 조회(R) 작업은 단순 데이터 조회인데, 동일 Domain Model로 처리하면 필요하지 않은 Domain 속성들로 인해 복잡도가 증가합니다.

따라서 이 문제를 해결하기위해서 명령을 처리하는 책임조회를 처리하는 책임분리하는 해법을 찾았고 이 방법이 CQRS입니다.


CQRS의 종류

전통적인 CRUD 시스템.

original-crud

기존의 전통적인 CRUD 시스템은 다음 그림과 같은 계층 구조를 지니고 있습니다. 이에 CQRS 패턴을 적용하기 위한 방법으로 크게 최소 3가지 방법이 있습니다.

1. Simple CQRS architecture

이는 단일 Data Store에 Command Query Model을 분리된 계층으로 나누는 방식입니다.

Simple CQRS architecture

해당 그림처럼 Database(RDBMS)는 분리하지 않고 기존 구조를 유지하고 Model Layer 부분과 Command와 Query Model로 분리하는 수준으로 간단하게 적용할 수 있습니다.

장점.

  • 훨씬 단순하게 구현 및 적용할 수 있습니다.

단점.

  • 동일한 Database 사용에 따른 성능상 문제점은 개선하지 못합니다.

2. CQRS with separated persistance mechanisms

CQRS with separated persistance mechanisms

해당 방법은 Command용 Database와 Query용 Database를 분리하고 별도의 Broker를 통해서 이 둘간의 Data를 동기화 처리하는 방식입니다. 이 경우에는 데이터를 조회하려는 서비스들은 서비스에 맞는 저장소를 선택할 수 있기 때문에 polyglot 구조로 구성할 수도 있습니다. 이 경우에는 각각의 Model에 맞게 저장소(RDBMS, NOSQL, Cache)를 튜닝해서 사용할 수 있습니다.

  • polyglot 이란? 다수의 Database를 혼용하여 사용하는 것입니다.

장점

  • Simple CQRS 에서 거론되는 Database 사용에 발생하는 성능 관점의 문제를 해결할 수 있습니다.

단점

  • 동기화 처리를 위한 Broker의 가용성과 신뢰도가 보장이 되어야합니다.

3. EventSouring Model

EventSouring Model

해당 방법은 이벤트 소싱(Event Sourcing)을 적용한 구조입니다.

이벤트 소싱이란 Application 내의 모든 Activity를 이벤트로 전환해서 이벤트 스트림(Event Stream)을 별도의 Database에 저장하는 방식을 의미합니다. EvensSourcing Model이란 이벤트 스트림을 저장하는 Database에는 오직 데이터 추가만 가능하고 계속적으로 쌓이는 데이터를 구체화시키는 시점에서 그때까지 구축된 데이터를 바탕으로 조회 대상 데이터를 작성하는 방법을 의미합니다. 즉, Application 내의 상태 변경을 이력으로 관리하는 패턴의 발전된 형태로 이해하면 됩니다.

이벤트 소싱의 이벤트 스트림은 오직 추가만 가능하고, 필요로 하는 시점에 구체화 단계를 가지게 되고 이 처리과정이 CQRS의 모델 분리 관점에서 잘 맞기 때문에 주로 선택한다.

CQRS 패턴에 이벤트 소싱은 필수가 아니지만 이벤트 소싱에는 CQRS가 필요합니다.


CQRS의 이점.

  • 독립적인 크기 조정

    • CQRS를 통해 읽기 및 쓰기의 워크로드를 독립적으로 확장할 수 있습니다.
  • 최적화된 데이터 스키마

    • 읽기 쪽에서는 쿼리에 최적화된 슼니마를 사용하고 쓰기에서는 업데이트에 최적화된 스키마를 사용할 수 있습니다.
  • 보안

    • 올바른 도메인 엔터티만 데이터에 쓰기를 수행할 수 있는지 쉽게 확인 가능합니다.
  • 유연한 모델 생성

    • 대부분의 복잡한 비즈니스 논리는 쓰기 모델로 이동시키고 읽기모델은 상대적으로 간단하게 정리하여 유지가능하고 유연한 모델을 만들 수 있습니다.
  • 단순한 쿼리

    • 읽기 데이터베이스에서 구체화된 뷰를 저장하여 쿼리 시 복잡한 조인을 방지할 수 있습니다.

마무리.

이전의 게시글과 오늘 게시글을 통해서 CQRS 패턴은 Database의 성능을 올리기 위해서 적용된 패턴이고 SAGA 패턴은 MSA환경에서의 데이터 일관성을 유지하기 위해 제안된 방법으로 이해하였습니다.

MSA에 대해 좀 더 공부해야하는 부분이나, 추가적으로 공부를 해야하는 부분이 있다면 다시 정리해보겠습니다. 회사 업무에서는 MSA 구조를 사용하는 일은 아직 없지만, 혹시라도 이후에 적용하게 되었을 때를 대비학는 의미 + 개인적인 호기심으로 글을 정리했습니다.


출처