적용하게 된 계기
2023 Smilegate Dev Camp를 참여하면서 진행하게 된 프로젝트에서 아키텍처를 설계하는 과정에서 Create, Update, Delete 요청에 비해 많은 Read 요청을 감당하기 위해 어떻게 해결할지 고민하다가 CQRS 패턴을 적용해 보기로 했다.
CQRS
CQRS는 CRUD에서 조회를 하는 부분인 Read를 다른 CUD에서 독립시켜 읽기 성능을 높이자는 취지에서 나온 패턴으로
Command Query Responsibility Segregation의 약자로 명령(Command)과 질의(Query)의 분리를 의미한다.
Command 모델과 Query 모델의 책임을 분리함에 따라 성능상의 이점을 가져갈 수 있다. ex) 필요에 따른 Query 모델 Scale-out
CQRS의 단계
CQRS는 다양한 방법으로 구현해 볼 수 있지만 단계적 분리를 통해 크게 3가지 방법으로 구현해 볼 수 있다.
1단계 : 모델의 분리를 통한 개념적 분리
이 단계의 CQRS는 데이터베이스를 분리하지 않고 Read model과 Write model을 개념적으로 분리하여 운용한다.
별도의 쿼리 및 업데이트 모델을 사용하면 디자인 및 구현이 간소화된다는 장점이 있지만, 성능적인 개선이나 확장성에는 변화가 없다.
2단계 : 데이터베이스의 물리적 분리
더 높은 격리 수준을 위해 Write data와 Read data를 물리적으로 분리하여 운용한다.
Command model에서는 Write data의 신뢰성을 위해 주로 도메인 주도 개발(DDD)을 통해 관리하고 정규화한다.
별도의 데이터베이스를 두고 운용하기 때문에 두 데이터베이스 간의 데이터 간극을 동기화를 통해 맞춰야 한다.
이를 위해 별도의 broker를 통해 데이터의 정합성을 유지한다.
3단계 : 이벤트 소싱을 통한 이벤트 기반 아키텍처
이벤트 소싱을 통한 이벤트 기반 아키텍처에서는 애플리케이션 상태를 이벤트의 시퀀스로 저장한다. 이때, 각 이벤트는 데이터에 대한 변경 집합을 나타낸다. 따라서 현재의 상태를 알고 싶다면 초기 상태에서 데이터에 대한 상태 변경 이벤트들을 재생하여 구축해야 한다.
이러한 방식의 CQRS는 명령과 조회를 비동기적으로 처리하여 부하를 분산시키고 성능을 향상시킨다.
하지만 비동기적으로 처리하기 때문에 강한 데이터 정합성과 실시간성을 필요로 하는 시스템에는 적합하지 않다.
CQRS의 이점
CQRS 패턴을 사용한다면 다음과 같은 이점을 얻을 수 있다.
- CQRS를 통해 읽기 및 쓰기 작업을 독립적으로 확장하고 더 적은 수의 lock 경합을 발생하게 할 수 있다.
- 읽기 쪽에서는 쿼리에 최적화된 스키마를 사용하고 쓰기 쪽에서는 업데이트에 최적화된 스키마를 사용할 수 있다. (데이터베이스의 물리적 분리에 따른 장점)
- 관심사의 분리를 통해 유지보수가 편하고 유연한 모델을 만들 수 있다.
- 읽기 데이터베이스에서 구체화된 뷰를 저장하여 쿼리 할 때 복잡한 조인을 방지할 수 있다.
구현 시 고려해야 할 부분
- 시스템이 지나치게 복잡해지는 것
- broker를 통한 메시징이 사용된다면, 메시지 전달 실패 시 발생하는 오류 및 중복 메시지에 대한 처리
- 읽기 데이터베이스와 쓰기 데이터베이스의 데이터 정합성
'Tech > Develop' 카테고리의 다른 글
[Spring Boot] '멀티 모듈이.. 뭐지..?' - 멀티 모듈 적용기(1) (0) | 2025.02.26 |
---|---|
MSA 환경 CQRS 패턴 적용기 - (2) 프로젝트에 적용해보기 (0) | 2024.08.07 |