CQRS 패턴

CQRS

Command Query Responsibility Segregation

CQRS 패턴은 데이터를 저장 & 수정하는 Command 작업과 조회하는 Query 작업을 분리하는 패턴으로, 복잡한 도메인 모델의 작업을 분리함으로서, 보다 단순화하고 유연성을 가질 수 있게 하는 목적이 있다.

CQRS 패턴 기본

위 그림처럼 CQRS 패턴은 Command 명령, Query 질의 서비스에 따라 다른 데이터베이스로 향하는 흐름을 가진다.

CommandQuery 를 분리하면 어떤 장단점이 있을지 살펴볼 필요가 있을 것 같다.


CQRS 패턴 장단점

장점

구분 설명
독립적인 스케일링 읽기 작업쓰기 작업에 대한 독립적인 스케일링 가능
최적화된 스키마 구성 각 작업에 맞는 다른 스키마 구성 가능
도메인 모델 단순화 복잡한 쓰기 작업 또는 읽기 작업이 분리되면서 도메인 모델 설계 단순화
보안성 강화 분리된 각 작업에 대한 다른 보안 체계 구성을 통한 보안성 강화

단점

구분 설명
구현 복잡성 CQRS 패턴을 위한 구현 방법과 이벤트 소싱 패턴과 같은 추가 개념 포함일 경우, 높은 구현 복잡성 이슈
데이터 동기화 이슈 쓰기 작업의 데이터에 대해 읽기 작업이 일관성이 깨지는 동기화 이슈
메시징 처리 이슈 CQRS 패턴 구현을 위해 메시징 기법 활용할 경우, 메시징 전달 실패 또는 중복 메시지 처리 이슈

Aggregate & Projection

CQRS 패턴을 제대로 이해하기 위해서는 AggregateProjection 의 개념도 함께 이해하고 있어야 한다.

Aggregate / Aggregator

Aggregate 는 도메인 모델에서 비즈니스 로직적으로 이뤄진 Entity & Value 의 집합 또는 Command 모델의 집합이다.

비즈니스 로직 수행 중에 연관되어 있는 도메인 모델이 해당 로직의 일부분만 적용되지 않는 비즈니스 원자성을 가지고 있어야 하며, 연관된 도메인 모델 사이엔 Transaction 관계가 존재해야 한다.

Projection / Projector

ProjectionCommand 모델에서 Query 모델로 변환하는 과정을 의미한다.

Command 모델이 저장된다는 것은 동시에 Query 모델도 함께 저장하는 것이기 때문에, Query 모델 구조에 맞게 Command 모델을 변환하고 그것을 Projection 이라고 한다.


동기화 문제

CQRS 패턴은 Command 모델과 Query 모델의 정보가 항상 동일해야 하는데, 그러기 위해서는 2개의 모델 간의 동기화는 필수이다.

하나의 저장소를 사용한다면 Transaction 처리를 통해 2개의 모델 동기화를 처리할 수 있지만, 만약 다른 저장소를 사용하게 된다면 다른 처리 방식이 필요하다.

Command 모델의 저장되는 이벤트가 발생하였을 때, 해당 이벤트를 받아 Query 모델로 저장하는 처리 방식은 정석적인 처리 방식이라고 한다.


정리

서비스 운영하다보면 간혹 데이터베이스의 쿼리 성능 저하로 운영 서비스에 장애가 발생하는 것을 많이 볼 수 있었다.

CQRS 패턴을 적용한다면, 조금 더 서비스 장애에 대한 부하가 줄어들 것이라 생각되어 정리하게 되었지만, CQRS 패턴을 정리하다보니, 이보다 더 중요한 개념은 이벤트-소싱 패턴도 있었고 이 또한 정리할 필요성이 있는 것 같다.


출처