CQRS(Command Query Responsibility Segregation)는 명령과 조회의 책임을 분리하는 소프트웨어 아키텍처 패턴입니다. CQRS는 복잡한 시스템의 설계 및 구현을 단순화하고 성능을 향상시키는 데 유용한 패턴입니다.
다음은 CQRS의 주요 개념과 장점에 대한 설명입니다:
1. 기본 개념:
- Command: 시스템의 상태를 변경하는 작업입니다.
예를 들어, 데이터베이스에 데이터를 추가하거나 수정하는 작업이 이에 해당합니다.
- Query: 시스템의 상태를 읽어오는 작업. 예를 들어, 데이터베이스에서 데이터를 조회하는 작업이 이에 해당.
- CQRS에서는 Command와 Query를 처리하는 모델을 분리하여 각각의 책임을 명확히 합니다.
2. 장점:
- 확장성: Command와 Query가 분리되어 있으므로 각각의 모델을 독립적으로 확장할 수 있습니다.
- 성능 최적화: 조회 작업을 최적화하기 위해 데이터 모델을 읽기 전용으로 설계할 수 있습니다.
- 복잡성 관리: 복잡한 도메인 로직을 명령 처리 부분에 집중시킬 수 있어 코드의 가독성과 유지보수성이 향상됩니다.
- 보안 강화: 명령과 조회의 책임을 분리함으로써 권한 관리가 용이해집니다.
3. CQRS와 Event Sourcing:
- Event Sourcing: 시스템의 상태를 이벤트의 시퀀스로 저장하는 방법입니다. CQRS와 함께 사용하면, 각 이벤트가 발생할 때마다 시스템의 상태가 변경되므로 상태의 일관성을 유지할 수 있습니다.
- 이벤트 소싱을 통해 시스템의 모든 변경 내역을 추적하고 재생할 수 있습니다.
4. 사용 사례:
- 복잡한 비즈니스 로직: 명령과 조회의 처리가 복잡한 비즈니스 도메인에서 유용합니다.
- 대규모 시스템: 높은 확장성과 성능이 요구되는 시스템에서 효과적입니다.
- 실시간 데이터 처리: 이벤트 소싱과 함께 사용하여 실시간 데이터 처리 및 분석에 활용할 수 있습니다.
Problem
서비스당 데이터베이스를 갖는 구조로 구현을 하고 나면, 여러 서비스의 공동 데이터를 필요로 하는 하는 쿼리가 요구될 수 있지만, 이것은 불가능하다. 어떻게 마이크로서비스 아키텍처에서 쿼리들을 구현할 수 있을까?
Solution
- CQRS는 애플리케이션을 커맨드, 쿼리 두개의 파트로 분할하는 것을 제안한다.
- 커맨드(Command) 파트는 생성, 업데이트, 삭제 요청을 담당한다.
- 쿼리(Query) 파트는 Materialized view를 사용하여 쿼리 부분을 처리한다.
- Event Sourcign(이벤트 소싱) 패턴이 주로 데이터 모든 변경에 대한 이벤트를 만들때 CQRS와 함께 사용된다.
- Materialized view는 이벤트 스트림의 구독을 통해 갱신된 상태로 유지한다.
Command, Query는 왜 분리하는가?
- 기존 아키텍처에서는 동일한 데이터 모델을 사용하여 데이터베이스를 쿼리하고 업데이트 한다. 이는 간단하고 기본 CRUD 작업에 적합하다.
- 그러나 더 복잡한 응용 프로그램에서는 이 접근 방식이 다루기 어려울 수 있다.. 예를 들어, 읽기 측에서 애플리케이션은 다양한 쿼리를 수행하여 다양한 형태의 데이터 전송 객체(DTO)를 반환할 수 있다. 개체 매핑이 복잡해질 수 있다.
- 쓰기 측면에서 모델은 복잡한 유효성 검사 및 비즈니스 논리를 구현할 수 있다.
- 결과적으로 너무 많은 작업을 수행하는 지나치게 복잡한 모델이 될 수 있다.
- 읽기 및 쓰기 워크로드는 성능 및 확장 요구 사항이 매우 다른 비대칭인 경우가 많다.
- 기존 접근 방식은 데이터 저장소 및 데이터 액세스 계층의 부하와 정보 검색에 필요한 쿼리의 복잡성으로 인해 성능에 부정적인 영향을 미칠 수 있다.
- 각 엔터티는 읽기 및 쓰기 작업의 대상이 되기 때문에 보안 및 권한 관리가 복잡해질 수 있으며, 이로 인해 잘못된 프로젝트에서 데이터가 노출될 수 있다.
CQRS의 이점
- 독립적인 확장. CQRS를 사용하면 읽기 및 쓰기 워크로드를 독립적으로 확장할 수 있으며 잠금 경합이 줄어들 수 있다.
- 최적화된 데이터 스키마. 읽기 쪽은 쿼리에 최적화된 스키마를 사용할 수 있고, 쓰기 쪽은 업데이트에 최적화된 스키마를 사용할 수 있다.
- 보안. 올바른 도메인 엔터티만 데이터에 대한 쓰기를 수행하고 있는지 확인하는 것이 더 쉽다.
- 우려의 분리. 읽기 쪽과 쓰기 쪽을 분리하면 유지 관리가 더 쉽고 유연한 모델이 될 수 있다. 복잡한 비즈니스 로직의 대부분은 쓰기 모델로 들어간다. 읽기 모델은 비교적 간단할 수 있다.
- 더 간단한 쿼리. 구체화된 뷰를 읽기 데이터베이스에 저장함으로써 애플리케이션은 쿼리할 때 복잡한 조인을 피할 수 있다.
CQRS 패턴의 진화
- CQRS의 패턴은 좀더 시스템 환경에 따라 DB Repository도 분리하여 진화하고 있다.
- 이런 진화의 전제는 MSA기반의 아키텍처 설계 및 Database per Service 기반환경으로 분리된 환경에서 적합하다.
- Command용 Query용 DB 분리는 CQRS 패턴에서 필수 사항은 아니며 업무특성 및 리소스 관리 및 비용을 고려하여 적용해야 한다.
- Query용 DB의 NoSQL은 옵션이며 업무 특성상 관계형 DB보다 NoSQL에 효율적인 경우 적용한다.
'IT 세상' 카테고리의 다른 글
Event Sourcing (0) | 2024.08.07 |
---|---|
Strangler 패턴 (0) | 2024.08.07 |
Architecture 설계 - 요구사항, Cloud Native, MSA (0) | 2024.08.05 |
Apache Kafka 개념 및 주요 기능, 사례 (0) | 2024.08.05 |
Redis(REmote DIctionary Server) 주요 개념 및 특징, 사례 (0) | 2024.08.05 |