CQRS가 필요한 이유

junto·2024년 8월 3일
0

database

목록 보기
7/7
post-thumbnail

CQRS (Command Query Responsibility Segregation)

  • 객체 지향으로 도메인 모델을 구현할 때 주로 사용하는 ORM 기법은 도메인 상태 변경 기능을 구현하는 데는 적합하지만, 주문 상세 조회 화면처럼 여러 애그리거트에서 데이터를 가져와 출력하는 기능을 구현하기에는 고려할 게 많아 구현을 복잡하게 한다.

  • 구현 복잡도를 낮추는 간단한 방법이 있는데, 바로 상태 변경을 위한 모델과 조회를 위한 모델로 분리하는 것이다. CQRS는 Command Query Responsibility Segragtaion의 약자로, 변경 기능을 위한 모델과 조회 기능을 위한 모델을 분리하는 패턴이다.

명령, 쿼리, 책임, 분리

  • 명령
    • 시스템 데이터 변경
    • 예시: 주문 취소, 배송 완료
  • 쿼리
    • 시스템 데이터 조회
    • 예시: 주문 목록
  • 책임
    • 구성 요소의 역할
    • 구성 요소(모델)
      • 클래스, 함수
      • 모듈/패키지
      • 웹서버/DB
  • 분리
    • 역할에 따라 구성 요소 나누기

명령 역할을 수행하는 구성 요소와 쿼리 역할을 수행하는 구성 요소를 나누는 것이 CQRS 핵심이다.

CQRS가 필요한 이유

  • 명령과 조회에 단일 모델을 사용하면, MEMBER 테이블에 LOGIN_HISTORY 테이블 필드가 추가되며, ORDER 테이블 관련 필들도 추가된다. 코드의 역할과 책임이 점점 모호해진다.
  • 상태를 변경하는 범위와 상태를 조회하는 범위가 정확하게 일치하지 않기 때문에 단일 모델로 두 종류의 기능을 구현하면 모델이 불필요하게 복잡해진다.

명령과 조회 모델 분리

  • JPA 기반 단일 도메인 모델을 사용하면 통계 값을 빠르게 조회하기 위해 JPA와 관련된 다양한 성능 관련 기능을 모델에 적용해야 한다. CQRS를 적용하면, 조회 모델을 별도로 만들기 때문에 도메인 모델이 복잡해지는 것을 방지한다.
    • 변경 기능 - JPA 활용(생성, 데이터 변경)
    • 조회 기능 - MyBatis, JDBC template, JPA 중 알맞은 기술 사용
  • 명령 모델은 트랜잭션을 지원하는 RDBMS를 사용하고, 조회 모델은 조회 성능이 좋은 메모리 기반 NoSQL도 사용할 수 있을 것이다.
  • 두 데이터 저장소간 데이터 동기화는 이벤트를 활용해 처리한다. 명령 모델에서 상태를 변경하면 이에 해당하는 이벤트가 발생하고, 그 이벤트를 조회 모델에 전달해서 변경 내역을 반영한다.
  • 명령 모델과 조회 모델이 서로 다른 데이터 저장소를 사용할 경우 데이터 동기화 시점에 따라 구현 방식이 달라질 수 있다. 명령 모델에서 데이터가 바뀌자마자 변경 내역을 바로 조회 모델에 반영해야 한다면 동기 이벤트와 글로벌 트랜잭션을 사용해 실시간으로 동기화할 수 있다. (성능 저하)
  • 특정 시간 안에만 동기화하면 된다면, 비동기로 데이터를 전송하면 된다.

장점

1. 명령 모델을 구현할 때 도메인 자체에 집중

  • 복잡한 도메인은 주로 상태 변경 로직이 복잡한데, 명령 모델과 조회 모델을 구분하면 조회 성능을 위한 코드가 명령 모델에 없으므로 도메인 로직을 구현하는 데 집중할 수 있다.

2. 명령 모델에서 조회 관련 로직이 사라져 복잡도 감소

3. 조회 성능 향상시키는 데 유리

  • 조회 전용 모델을 사용하기에 조회 성능을 높이기 위한 코드가 명령 모델에 영향을 주지 않는다.

단점

1. 구현해야 할 코드가 많음

  • 도메인이 복잡하거나 대규모 트래픽이 발생하는 서비스라면 조회 전용 모델을 만드는 것이 향후 유지보수에 더 유리하다. 도메인이 복잡하지 않은데, CQRS를 도입하면 두 모델을 유지하는 비용만 커지고 얻을 수 있는 이점은 없다.

2. 구현해야 할 기술이 더 많이 필요 (이벤트)

  • 데이터 동기화를 위해 메시징 시스템을 도입해야 할 수도 있다.

참고자료

  • 도메인 주도 개발 시작하기 - 최범균, 유튜브 영상 참고
profile
꾸준하게

0개의 댓글