CQRS

2023. 9. 21. 07:49스터디/DDD 스터디

728x90

보통 데이터를 조회 시에 여러 에그리거트에서 데이터를 가져와야 한다. 

여러 애그리거트의 데이터가 필요하면 다양한 방안의 구현 방법을 고민해야 하는데, 식별자를 이용해서 애그리거트를 참조하는 방식을 사용하면 즉시 로딩과 같은 JPA 쿼리 관련 최적화 기능을 사용할 수 없다.

 

직접 참조하는 방식을 사용한다 하더라도, 같은 연관도 즉시/지연 로딩 등 다양한 방법으로 처리애햐 하고, DBMS가 제공하는 전용 기능이 필요하면 네이티브 쿼리를 사용해야 할 수도 있다. 

 

ORM 기법은 도메인 상태 변경 기능을 구현하는 데는 적합하지만, 데이터를 가져와 출력하는 기능울 구현하기에는 고려할게 많아서 구현을 복잡하게 한다.

 

상태 변경을 위한 모델과 조회를 위한 모델을 분리하면 위 문제를 해결할 수 있다.

 

# CQRS

 

시스템의 기능은 크게 두 가지이다.

1. 상태를 변경하는 기능

2. 상태 정보를 조회하는 기능

 

상태 변경 기능은 주로 한 애그리거트의 상태를 변경한다.

반면, 조회 기능은 두 개 이상의 애그리거트가 필요할 때가 많다.

 

상태를 변경하는 범위와 조회하는 범위가 일치하지 않기 때문에 단일 모델로 두 종류의 기능을 구현하면 모델이 불필요하게 복잡해진다.

 

위 복잡도를 해결하기 위해 사용하는 방법이 CQRS이다. 

CQRS : 명령(Command)을 위한 모델과 조회(Query)를 위한 모델을 분리하는 패턴

CQRS는 복잡한 도메인에 적합하다.

CQRS를 사용하면 각 모델에 맞는 구현 기술을 선택할 수 있다.

예를 들어 명령 모델은 객체지향에 기반하여 도메인 모델을 구현하기에 JPA를 사용하고 ,

조회 모델은 SQL로 데이터 조회할 때 좋은 마이바티스를 사용해서 구현하면 된다.

 

조회 모델에는 응용 서비스가 없어도 된다.

물론 데이터 표현 영역에 전달하는 과정에서 로직이 필요하면 응용 서비스를 자율적으로 추가해도 된다.

커멘드 모델은 객체를 기반으로 한 도메인 모델을 이용하고,

쿼리 모델은 응답에 필요한 정보를 담는 데이터 타입을 이용한다.

커멘드 모델은 상태를 변경하는 도메인 로직을 수행하는 데 초점이 있고,

조회 모델은 화면에 보여줄 데이터를 조회하는 데 초점이 있다. 

@Subselect를 이용하면 조회 모델을 쉽게 분리할 수 있다.

 

커멘드와 쿼리를 아예 다른 데이터 저장소로 사용할 수 있다.

커멘드 모델은 RDB를 사용하고,

조회 모델은 조회 성능에 좋은 NoSql를 사용할 수 있다. 

두 데이터 간 동기화는 이벤트를 활용하여 처리한다.

명령 모델에서 데이터가 바뀌자마자 조회 모델에 반영해야 한다면, 동기 이벤트와 글로벌 트랜젝션을 사용하여 실시간으로 동기화 할 수 있다.

특정 시간 안에만 동기화 해도 된다면, 비동기로 데이터를 전송하면 된다.

 

일반적으로 웹서비스는 상태 변경 요청보다, 조회하는 요청이 많다.

메모리에 캐싱하는 데이터는 DB에 보관된 데이터를 그대로 저장하기 보다는 변환한 데이터를 캐싱할 때 성능에 더 유리하다.

조회 속도를 높이기 위해서 병도 처리를 하고 있다면 명시적으로 CQRS 패턴을 적용하는게 좋다.

 

CQRS 패턴을 통해 명령 모델을 구현하면 도메인 자체에 집중할 수 있다는 장점이 있다. 

또한, 캐시적용이나 조회쿼리 튜닝 등을 통해 조회 성능을 향상시킬 수 있다.

물론, 구현할 코드가 많아진다는 문제점이 있고, 메시징 시스템 같은 더 많은 구현 기술이 필요할 수도 있다는 단점이 있다.

장단점을 고려했을 때, 도메인이 복잡하지 않을 때 CQRS를 도입하면 유지비용만 높아지고 이점이 없는 문제가 있다!

728x90

'스터디 > DDD 스터디' 카테고리의 다른 글

이벤트  (1) 2023.09.09
도메인 모델과 바운디드 컨텍스트  (0) 2023.09.02
애그리거트 트랜잭션 관리  (0) 2023.08.26
도메인 서비스  (0) 2023.08.18
응용 서비스와 표현 영역  (0) 2023.08.12