성장, 그리고 노력

부족하더라도 어제보다 더 잘해지자. 노력은 절대 배신하지 않는다.

CQRS

CQRS 패턴 개념

제이콥(JACOB) 2020. 7. 5. 14:43

기존 아키텍처

일반적인 애플리케이션은 쿼리하고 업데이트를 하는 것에 동일한 데이터 모델을 사용한다. 

이미지 출처: https://docs.microsoft.com

 간단한 애플리케이션에서는 이것이 적합하다. 하지만 애플리케이션이 복잡해질수록 위 방법은 어려워진다. 왜냐하면 애플리케이션은 읽기 쪽에서 다른 쿼리를 실행할 수 있고, 그러면 모양이 다른 DTO를 반환하기 때문에 개체 매핑이 복잡해지기 때문이다. 또한 동일한 데이터 집합에서 작업을 병렬로 수행할 때 데이터 경합이 발생할 수 있으며, 데이터 저장소 및 데이터 액세스 계층에 대한 로드 및 정보를 검색하는데 필요한 쿼리의 복잡성으로 성능에 부정적인 영향을 미칠 수 있다. 그리고 각 엔터티는 읽기 및 쓰기 작업의 대상이 되므로 잘못된 컨텍스트에서 데이터를 노출할 수 있으으로 보안 및 사용 권한 관리가 복잡해질 수 있다. 

 

CQRS

CQRS - Command and Query Responsibility Segregation
ES - Event Sourcing

 반면 CQRS는 명령(command, 데이터 저장소(DB)에 대한 업데이트) 및 쿼리(query, 데이터 저장소(DB)에 대한 읽기)의 책임을 분리하는 패턴이다. CQRS를 구현하면 성능, 확장성 보안을 극대화할 수 있다. 

이미지 출처: https://docs.microsoft.com

이 패턴에서 명령은 데이터 중심이 아닌 작업을 기반으로 해야하며('예약 호텔 객실'이 아니라 '예약 상태를 예약상태로 설정'), 비동기 처리를 위해 큐에 배치될 수도 있다. 또한 쿼리는 데이터베이스를 수정하지 않으며, 쿼리는 도메인 정보를 캡슐화하지 않는 DTO를 반환한다. 

그림1-1. 이미지 출처: cqrs_journey_guide

 읽기 저장소는 쓰기 저장소의 읽기 전용 복제본이거나 읽기 및 쓰기 저장소가 전혀 다른 구조일 수도 있다. 여러 읽기 전용 복제본을 사용하면 쿼리의 성능이 당연히 향상될 수 있으며, 부하를 감안하여 각 저장소를 적절하게 확장할 수도 있다. 예를 들어 보통 읽기 저장소는 쓰기 저장소보다 부하가 훨씬 높다.

그림1-2. 이미지 출처: https://docs.microsoft.com

 메모리 내 모델은 동일한 데이터베이스를 공유할 수 있으며, 이 경우 데이터베이스는 두 모델 간의 통신 역할을 한다. 그림 1-2와 같이 여러 형태로 변형을 하여 CQRS를 적용할 수 있다. 별도의 데이터베이스를 하용하며 쿼리측 데이터베이스를 실시간 리포팅 데이터베이스(Reporting Database)로 만들 수도 있다. 이 경우 두 모델 또는 데이터베이스 간에 통신 메커니즘이 추가되어야 한다. 

고려할 점

1. CQRS는 많은 경우 이벤트 소싱 패턴을 함께 사용하여 구현한다. CQRS의 기본 개념은 간단하지만 이벤트 소싱 패턴을 포함하는 경우 복잡한 애플리케이션 디자인이 만들어질 수 있다. 

2. CQRS는 메시징이 필요하지는 않지만, 명령을 처리하고 업데이트 이벤트를 게시하는데 공통적으로 메시징을 사용한다. 이 경우 애플리케이션은 메시지 오류 또는 중복 메시지를 처리해야 한다. 

3. 읽기 및 쓰기 데이터베이스를 구분하는 경우 읽기 데이터는 기한이 경과되었을 수도 있다. 읽기 모델 저장소는 쓰기 모델 저장소의 변경 내용을 반영하도록 업데이트되어야 하며 사용자가 오래된 읽기 데이터를 기반으로 요청을 발행한 경우를 감지하기 어려울 수도 있다. 

 

그렇다면 언제 사용해야될까?

1. 많은 사용자가 동일한 데이터에 병렬로 액세스 하는 공동작업 도메인일 경우

2. 개발자 중 한 팀은 쓰기 모델에 포함되는 복잡한 도메인 모델에 집중하고 다른 한 팀은 읽기 모델과 사용자 인터페이스에 집중할 수 있다면.

3. 시스템이 시간이 지나면서 진화할 것으로 예상되어 여러 버전의 모델을 포함할 수 있거나 비즈니스 규칙이 정기적으로 변하는 시나리오.

4. 가장 가치 있는 시스템의 제한된 구역에 CQRS 적용을 고려해야 한다. (도메인 또는 비즈니스 규칙이 간단하거나 간단한 CRUD 스타일의 사용자 인터페이스와 데이터 액세스 작업만으로 충분하다면 CQRS는 어울리지 않는다, 모든 상황에서 최상단에 패턴으로 CQRS는 위치하는 건 어디에서도 추천하지 않는 방법이다) DDD 용어에서 말하는 시스템 전체가 아닌 시스템의 특정 부분(Bounded Context)에만 사용하자.

5. CQRS는 이벤트 기간 프로그래밍 모델에 적합하다. CQRS 시스템이  Event Collaboration과 통신하는 별도의 서비스로 분리되는 것이 일반적이며, 이를 통해 이벤트 소싱을 쉽게 이용할 수 있다. 

 

cf)  Event Collaboration: 이벤트 협업(?), 여러 구성 요소는 내부 상태가 변경될 때 이벤트를 보내 서로 통신하여 함께 작동한다. 이것의 장점이자 장점은 구성 요소 간에 매우 느슨한 결합을 제공한다는 것이다. 기존 구성 요소가 새로운 도착에 대해 알 필요 없이 시스템에 새 구성 요소를 쉽게 추가할 수 있다. 새로 온 사람들이 이벤트를 듣는다면, 그들은 협력할 수 있다. 또한 시스템 고장에 대해서도 탄력적이다. 각 구성 요소는 작동에 대한 필요한 모든 것을 갖추고 있으므로 외부 세계와의 통신이 끊긴 경우에도 계속 동작할 수 있다. 물론 이때 어떠한 작업으로 이벤트를 수신하지 않게 된다면 오래된 정보로 작동하므로 다른 문제가 발생될 수도 있다. 

 

 

 

bliki: CQRS

CQRS (Command Query Responsibility Segregation) is the notion that you can use a different model to update information than the model you use to read information

martinfowler.com

 

반응형