도메인 주도 개발 스터디

Chapter 11 CQRS

막이86 2023. 11. 9. 16:40
728x90

도메인 주도 개발 시작하기 11장을 요약한 내용입니다.

11.1 단일 모델의 단점

  • 주문 내역 조회 기능을 구현하려면 여러 애그리거트에서 데이터를 가져와야 한다.
    • Order에서 주문 정보
    • Product에서 상품 정보
    • Member에서 회원 이름과 ID 정보
  • 조회 화면 특성상 조회 속도가 빠를수록 좋은데 여러 애그리거트의 데이터가 필요하면 구현 방법을 고민 해야함
    • 애그리거트 간 연관의 식별자가 아니라 직접 참조하는 방식으로 연결해도 고민거리가 생긴다.
    • 조회 화면 특성에 따라 같은 연관도 즉시 로딩이나 지연 로딩으로 처리 해야하기 때문
  • 조회 기능을 구현할 때 DBMS가 제공하는 전용 기능이 필요하면 JPA의 네이티브 쿼리를 사용해야할 수 있다.
  • 고민이 발생하는 이유는 시스템 상태를 변경할 때와 조회할 때 단일 도메인 모델을 사용하기 때문
    • ORM 기법은 도메인 상태 변경 기능을 구현하는 데는 적합하지만 조회 화면처럼 여러 애그리거트에서 데이터를 가져와야 출력하는 기능을 구현하기에는 고려할게 많음
  • 구현 복잡도를 낮추는 간단한 방법은 상태 변경을 위한 모델과 조회를 위한 모델을 분리하는 것

11.2 CQRS

  • 시스템이 제공하는 기능은 크게 두가지로 나눌 수 있다.
    1. 상태를 변경하는 기능
      1. 새로운 주문을 생성
      2. 배송지 정보를 변경
      3. 회원 암호를 변경
    2. 상태 정보를 조회하는 기능
      1. 주문 상세 내역 보기
      2. 게시글 목록 보기
      3. 회원 정보 보기
  • 도메인 모델 관점에서 상태 변경 기능은 주로 한 애그리거트의 상태를 변경
    • 주문 취소 기능과 배송지 정보 변경 기능은 한개의 애그리거트를 변경
    • 조회 기능에 필요한 데이터를 표시하려면 두 개 이상의 애그리거트가 필요할 때가 많다.
  • 단일 모델을 사용할 때 발생하는 복잡도를 해결하기 위해 사용하는 방법이 CQRS다
  • CQRS(Command Query Responsibility Segregation) 는 상태를 변경하는 명령(Command)을 위한 모델과 상태를 제공하는 조회(Query)를 위한 모델을 분리하는 패턴
  • CQRS는 복잡한 도메인에 적합
    • 도메인이 복잡할 수록 명력 기능과 조회 기능이 다루는 데이터 범위에 차이가 난다
    • 단일 모델로 처리하면 조회 기능의 로딩 속도를 위해 모델 구현이 필요 이상으로 복잡해짐
    • 주문/판매 통계 조회를 만들 경우
      • JPA기반 단일 도메일 모델을 사용하면 통계 값을 빠르기 조회하기 위해 JPA와 관련된 다양한 성능 관련 기능을 모델에 적용 해야함
    • CQRS를 적용하면 통계를 위한 조회 모델을 별도로 만들기 때문에 조회 기능 때문에 도메인 모델이 복잡해지는 것을 막을 수 있음
  • CQRS를 사용하면 각 모델에 맞는 구현 기술을 선택할 수 있다.
    • 명력 모델은 객체지향에 기반해서 도메인 모델을 구현하기에 적당한 JPA를 사용
    • 조회 모델은 DB 테이블에서 SQL로 데이터를 조회할 때 좋은 마이바티스를 사용해서 구현하면 된다.
  • 명령 모델과 조회 모델의 설계 예
    • 상태 변경을 위한 명령 모델은 객체를 기반으로 한 도메인 모델을 이용해서 구현
    • 조회 모델은 주문 요약 목록을 제공할 때 필요한 정볼르 담고 있는 데이터 타입을 이용
  • 명령 모델과 조회 모델이 같은 구현 기술을 사용할 수도 있다.
  • 명령 모델과 조회 모델이 서로 다른 데이터 저장소를 사용할 수도 있다.
    • 두 데이터 저장소간 데이터 동기화는 이벤트를 활용해서 처리
    • 데이터 동기화 시점에 따라 구현 방식이 달라질 수 있다.
      • 데이터가 바뀌자마자 변경 내역을 바로 조회 모델에 반영해야 한다면 동기 이벤트와 글로벌 트랜잭션을 사용해서 실시간으로 동기화
        • 동기 이벤트와 글로벌 트랜잭션을 사용하면 전반적인 성능이 떨어지는 단점
      • 특정 시간안에만 동기화해도 된다면 비동기로 데이터를 전송하면 된다.
        • 통계 데이터의 경우 1시간 단위로 최근 데이터를 반영해도 문제가 되지 않는다.

11.2.1 웹과 CQRS

  • 일반적인 웹 서비스는 상태를 변경하는 요청보다 상태를 조회하는 요청이 많다.
  • 포털이나 대형 온라인 쇼핑몰과 같이 조회 기능 요청 비율이 월등히 높은 서비스를 만드는 개발팀은 조회 성능을 높이기 위해 다양한 기법을 사용한다.
    • 쿼리 최적화
    • 메모리에서 조회 데이터를 캐싱
    • 조회 전용 저장소
  • 조회 성능을 높이기 위해 다양한 기법을 사용하는 것은 결과 적으로 CQRS를 적용하는 것과 같은 효과
    • 메모리에 캐싱 하는 데이터는 DB에 보관된 데이터를 그대로 저장하기 보다 화면에 맞는 모양으로 변환한 데이터를 캐싱할 때 성능에 더 유리
    • 쿼리를 최적화한다는 것은 조회 화면에 보여줄 데이터를 빠르게 읽어올 수 있도록 쿼리를 작성
  • 대규모 트랙픽이 발생하는 웹 서비스는 알게 모르게 CQRS를 적용하게 된다.
    • 조회 속도를 높이기 위해 별도 처리를 하고 있다면 명시적으로 명력 모델과 조회 모델을 구분하자
    • 조회 기능 때문에 명령 모델이 복잡해지는 것을 막을 수 있다
    • 조회 기능에 특화된 구현 기법을 보다 쉽게 적용할 수 있다.

11.2.2 CQRS 장단점

  • CQRS 패턴을 적용할 때 얻을 수 있는 장점은 명령 모델을 구현할 때 도메인 자체에 집중할 수 있다
    • 조회 성능을 위한 코드가 명령 모델에 없으므로 도메인 로직을 구현하는데 집중할 수 있다.
    • 조회 단위로 캐시 기술을 적용할 수 있다
    • 조회 전용 저장소를 사용하면 조회 처리량을 대폭 늘릴 수 있다.
    • 조회 전용 모델을 사용하기 때문에 조회 성능을 위한 코드가 명령 모델에 영향을 주지 않는다.

단점

  1. 구현할 코드가 더 많다
    1. 도메인이 복잡하거나 대규모 트래픽이 발생하는 서비스라면 조회 전용 모델을 만드는 것이 향후 유지 보수에 유리
    2. 도메인이 단순하거나 트래픽이 많지 않은 서비스라면 조회 전용 모델을 따로 만들 때 얻는 이점이 있는지 따져봐야 한다.
  2. 더 많은 구현 기술이 필요하다
    1. 명령 모델과 조회 모델을 다른 구현 기술을 사용해서 구현하기도 하고 경우에 따라 다른 저장소를 사용하기도 한다.
    2. 데이터 동기화를 위한 메시징 시스템을 도입해야 할 수도 있다.
  • 장단점을 고려해서 CQRS 패턴을 도입할지 여부를 결정해야 한다.
    • 도메인이 복잡하지 않은데 CQRS를 도입하면 두 모델을 유지하는 비용만 높아지고 얻을 수 있는 이점은 없다.
728x90