CQRS
Command Query Responsibility Segregation
CQRS 패턴은 데이터를 저장 & 수정하는 Command
작업과 조회하는 Query
작업을 분리하는 패턴으로,
복잡한 도메인 모델의 작업을 분리함으로서, 보다 단순화하고 유연성을 가질 수 있게 하는 목적이 있다.
위 그림처럼 CQRS 패턴은 Command 명령
, Query 질의
서비스에 따라 다른 데이터베이스로 향하는 흐름을 가진다.
Command
와 Query
를 분리하면 어떤 장단점이 있을지 살펴볼 필요가 있을 것 같다.
CQRS 패턴 장단점
장점
구분 | 설명 |
---|---|
독립적인 스케일링 | 읽기 작업과 쓰기 작업에 대한 독립적인 스케일링 가능 |
최적화된 스키마 구성 | 각 작업에 맞는 다른 스키마 구성 가능 |
도메인 모델 단순화 | 복잡한 쓰기 작업 또는 읽기 작업이 분리되면서 도메인 모델 설계 단순화 |
보안성 강화 | 분리된 각 작업에 대한 다른 보안 체계 구성을 통한 보안성 강화 |
단점
구분 | 설명 |
---|---|
구현 복잡성 | CQRS 패턴을 위한 구현 방법과 이벤트 소싱 패턴과 같은 추가 개념 포함일 경우, 높은 구현 복잡성 이슈 |
데이터 동기화 이슈 | 쓰기 작업의 데이터에 대해 읽기 작업이 일관성이 깨지는 동기화 이슈 |
메시징 처리 이슈 | CQRS 패턴 구현을 위해 메시징 기법 활용할 경우, 메시징 전달 실패 또는 중복 메시지 처리 이슈 |
Aggregate & Projection
CQRS 패턴을 제대로 이해하기 위해서는 Aggregate
와 Projection
의 개념도 함께 이해하고 있어야 한다.
Aggregate / Aggregator
Aggregate
는 도메인 모델에서 비즈니스 로직적으로 이뤄진 Entity & Value
의 집합 또는 Command
모델의 집합이다.
비즈니스 로직 수행 중에 연관되어 있는 도메인 모델이 해당 로직의 일부분만 적용되지 않는 비즈니스 원자성을 가지고 있어야 하며, 연관된 도메인 모델 사이엔 Transaction 관계가 존재해야 한다.
Projection / Projector
Projection
은 Command
모델에서 Query
모델로 변환하는 과정을 의미한다.
Command
모델이 저장된다는 것은 동시에 Query
모델도 함께 저장하는 것이기 때문에,
Query
모델 구조에 맞게 Command
모델을 변환하고 그것을 Projection
이라고 한다.
동기화 문제
CQRS 패턴은 Command
모델과 Query
모델의 정보가 항상 동일해야 하는데, 그러기 위해서는 2개의 모델 간의 동기화는 필수이다.
하나의 저장소를 사용한다면 Transaction
처리를 통해 2개의 모델 동기화를 처리할 수 있지만, 만약 다른 저장소를 사용하게 된다면 다른 처리 방식이 필요하다.
Command
모델의 저장되는 이벤트가 발생하였을 때, 해당 이벤트를 받아 Query
모델로 저장하는 처리 방식은 정석적인 처리 방식이라고 한다.
정리
서비스 운영하다보면 간혹 데이터베이스의 쿼리 성능 저하로 운영 서비스에 장애가 발생하는 것을 많이 볼 수 있었다.
CQRS 패턴을 적용한다면, 조금 더 서비스 장애에 대한 부하가 줄어들 것이라 생각되어 정리하게 되었지만, CQRS 패턴을 정리하다보니, 이보다 더 중요한 개념은 이벤트-소싱 패턴도 있었고 이 또한 정리할 필요성이 있는 것 같다.