아키텍처

CQRS (Command Query Read Segregation)

BUST 2018. 8. 20. 22:57

CQRS (Command Query Read Segregation)

  • 데이터를 업데이트하는 작업과 데이터를 읽는 작업을 분리를 하는 패턴이다.
  • Microsoft에서 CQRS 내용을 정리한 글이다.

기존 시스템 (CRUD)의 문제점

기존 CRUD 아키텍처

  • 여러 작업자가 동일한 데이터 집합을 동시에 사용하는 공동 작업 도메인의 데이터 저장소에 레코드가 잠겨 있는 경우 데이터 경합을 초래할 위험이 있다
    • 낙관적 잠금을 사용하는 경우 동시 업데이트로 인해 업데이트 충돌이 발생할 수 있습니다.시스템의 복잡성과 처리량이 늘어날수록 증가합니다.
    • 기존의 접근 방식은 데이터 저장소와 데이터 액세스 계층에 가해지는 부하뿐 아니라 정보를 검색하는 데 필요한 쿼리의 복잡성으로 인해 성능에 좋지 않은 영향을 미칠 수 있습니다.
  • 작업의 일부로 필요하지 않더라도 정확하게 업데이트되어야만 하는 추가 열이나 속성과 같이 데이터의 읽기와 쓰기 표현 사이에 불일치가 나타나는 경우가 많습니다.

해결방법 (CQRS)

  •  별도의 인터페이스를 사용하여 데이터를 업데이트하는 작업(명령)에서 데이터를 읽는 작업(쿼리)을 분리하는 패턴

기본 CQRS 아키텍처
  • 하나의 저장소에서 데이터를 쓸때의 Model와 읽을때의 Model를 다르게 두는 방법
    • SQL의 View 기능을 활용할수 있다.
    • projection view
  • 쓰기 Model에서는 복잡한 유효성 검사, 도메인의 논리 등을 통하고 저장이 된다.
  • 읽기 Model에서는 쓰기 Model의 복잡한 과정이 거의 없다.
  • Java에서 Write/Update/Delete Service 로직와 Read Service을 나누는 방법과 동일

보통은 아래와 같은 구조의 CQRS 패턴을 구현한다.


읽기 및 쓰기 저장소가 분리된 CQRS 아키텍처
  • 성능, 확장성, 보안을 최대화하기 위해 데이터를 여러 물리적 저장소로 분리한다.
  • 읽기 저장소는 쓰기 저장소의 읽기 전용 복제본이거 쓰기 저장소와 완전히 다른 저장소일수도 있다.
  • 데이터의 읽기저장소는 구체화된 뷰 패턴을 활용할수있다.

이 패턴을 사용해야 하는 경우

  • 여러 작업이 동일한 데이터에서 동시에 수행되는 공동 작업 도메인. 
  • 데이터 읽기 성능을 데이터 쓰기 성능과 별도로 세밀하게 조정해야 하는 시나리오(특히 읽기/쓰기 비율이 매우 높고 수평 확장이 필요한 경우)
    • 보통 이런 경우에는 cache (redis, memcache)를 활용하여 read 성능을 늘린다.

구체화된 뷰 패턴 (Materialization view Pattern)

그림 1은 구체화된 뷰 패턴을 사용할 수 있는 방법의 예를 보여 줍니다.
  • 결과 집합에 적합한 형식으로 데이터를 구체화하는 뷰를 미리 생성하는 패턴
  • 응용 프로그램에서의 데이터는 여러개의 테이블로 구현이 되지만, 구체화된 뷰에서는 join의 결과로 한번에 데이터를 보여줄수 있다.
그림 2: 구체화된 뷰 패턴을 사용하여 매출액 요약 생성

Reference

https://docs.microsoft.com/ko-kr/azure/architecture/patterns/materialized-view