[Architecture] CQRS 패턴

2025. 4. 24. 15:53TIL/Database

CQRS란?

  • CQRS(Command Query Responsibility Segregation)는 명령(Command)과 조회(Query)의 책임을 분리하는 아키텍처 패턴이다.
  • 전통적인 시스템은 동일한 데이터 모델과 경로를 통해 읽기와 쓰기를 처리하지만, CQRS는 이를 분리하여 각기 독립적인 모델로 관리한다.
  • 복잡한 도메인 로직이 존재하거나, 읽기 성능의 최적화가 중요한 시스템에서 효과적으로 사용된다.

CQRS의 구조

  • Command 모델
    데이터의 변경을 담당한다. 생성, 수정, 삭제와 같은 작업이 여기에 포함된다. 복잡한 비즈니스 로직이나 도메인 규칙이 이 모델에 포함되는 경우가 많다.
  • Query 모델
    데이터의 조회를 담당한다. 사용자 화면에 데이터를 빠르게 제공할 수 있도록 최적화된 구조를 가진다. 도메인 로직은 거의 없거나 아예 포함되지 않는다.
  • 읽기와 쓰기를 서로 다른 경로, 데이터 구조, 심지어 서로 다른 데이터베이스로 분리할 수 있다.

CQRS의 예시

  • 사용자가 자막을 추가, 수정, 삭제하는 작업은 Command 모델을 통해 이벤트로 저장한다.
  • 사용자가 자막 리스트를 확인하는 작업은 Query 모델을 통해 최적화된 데이터로 제공한다.
Command: POST /subtitles → 이벤트 저장
Query: GET /subtitles → 최적화된 리스트 반환
  • 자막과 관련된 이벤트는 subtitle_events에 저장된다.
  • 읽기 모델에서는 subtitle_read_model 또는 캐시 기반 데이터베이스를 사용해 가공된 자막 정보를 제공한다.

CQRS의 장점

  • 확장성 확보
    읽기와 쓰기를 독립적으로 확장할 수 있다. 특히 읽기 요청이 많은 시스템에서 성능 병목을 해소할 수 있다.
  • 책임 분리
    Command와 Query를 독립적으로 설계하고 운영할 수 있어, 유지보수가 수월하다.
  • 데이터 최적화
    조회 모델을 사용자 인터페이스에 최적화된 형태로 설계할 수 있다. 예를 들어 조인을 제거하거나 중첩된 구조로 제공할 수 있다.
  • 이벤트 소싱과의 높은 궁합
    Command 모델은 이벤트를 기록하고, Query 모델은 해당 이벤트를 기반으로 상태를 재구성한다.

CQRS의 단점

  • 복잡도 증가
    단일 모델 구조보다 설계와 구현이 복잡해진다. 특히 데이터 정합성을 보장하기 위한 전략이 필요하며, eventual consistency를 고려해야 한다.
  • 인프라 관리 비용 증가
    Command와 Query를 별도의 데이터베이스나 메시지 브로커로 분리할 경우, 인프라가 추가되고 관리 비용이 상승한다.
  • 동기화 이슈
    쓰기 작업 직후 바로 조회하는 경우, 읽기 모델에 최신 데이터가 반영되지 않아 지연이 발생할 수 있다.