Files
2nd/10_Wiki/Topics/CQRS.md
T
2026-05-02 23:49:32 +09:00

4.8 KiB

category, tags, title, description, last_updated
category tags title description last_updated
Unified
Architecture
Design Patterns
CQRS
Microservices
DDD
CQRS (Command Query Responsibility Segregation) 데이터의 상태를 변경하는 명령(Command)과 데이터를 조회하는 쿼리(Query)의 책임을 논리적 또는 물리적으로 분리하는 아키텍처 패턴 2026-05-02

CQRS (Command Query Responsibility Segregation)

📌 Brief Summary

**CQRS(Command Query Responsibility Segregation)**는 시스템에서 데이터를 읽는 작업(Query)과 데이터를 쓰는 작업(Command)을 분리하는 아키텍처 패턴입니다. 복잡한 비즈니스 로직을 처리하는 쓰기 모델과 빠른 성능이 필요한 읽기 모델을 분리함으로써, 각각에 최적화된 데이터베이스 기술과 코드를 사용할 수 있게 합니다. 특히 도메인 주도 설계(DDD)와 이벤트 기반 아키텍처(EDA) 환경에서 성능 병목을 해결하고 시스템의 복잡성을 낮추는 핵심 전략으로 활용됩니다.


📖 Core Content

1. 근본 원리: 책임의 완벽한 분리

  • Command (명령): 시스템의 상태를 변경합니다. 데이터의 무결성과 비즈니스 규칙을 보장해야 하므로 무거운 객체 지향 모델이나 ORM(TypeORM, Prisma 등)을 사용하여 트랜잭션을 엄격히 관리합니다. 리턴 값으로 데이터를 반환하지 않습니다.
  • Query (조회): 상태를 변경하지 않고 데이터만 반환합니다. 복잡한 비즈니스 로직을 생략하고, 조인이나 뷰에 최적화된 가벼운 SQL 쿼리 빌더(Slonik, Kysely 등)를 사용하여 성능을 극대화합니다.

2. 하이브리드 패턴 (Hybrid Approach)

단일 데이터베이스를 사용하더라도 코드 레벨에서 읽기와 쓰기의 모델을 분리하는 방식입니다. 이는 물리적 분리로 인한 복잡성을 피하면서도 코드의 응집도를 높일 수 있어 NestJS와 같은 프레임워크 실무에서 매우 효과적입니다.

3. 이벤트 소싱(Event Sourcing)과의 결합

CQRS는 종종 상태의 최종 형태가 아닌 상태를 변경시킨 모든 '이벤트'를 순차적으로 저장하는 이벤트 소싱과 함께 사용됩니다. 쓰기 모델에서 이벤트가 발생하면, 이를 비동기적으로 읽기 모델(Read Model)에 동기화하여 고도로 최적화된 뷰(View)를 생성합니다.


⚖️ Trade-offs & Caveats

Benefits

  • 독립적인 스케일링: 읽기 작업이 압도적으로 많은 시스템에서 읽기 데이터베이스와 인프라만 별도로 확장할 수 있습니다.
  • 모델 단순화: 쓰기 로직에 복잡한 조회용 DTO가 섞이는 것을 방지하여 도메인 모델(Entity)을 순수하게 유지할 수 있습니다.
  • 보안 및 권한 분리: 데이터를 변경하는 권한과 읽는 권한을 시스템 아키텍처 레벨에서 원천적으로 분리할 수 있습니다.

⚠️ Challenges

  • 시스템 복잡도 폭발: 두 개의 서로 다른 모델(또는 데이터베이스)을 관리해야 하므로 코드량과 인프라 설정이 크게 증가합니다. 단순한 CRUD 앱에는 치명적인 오버엔지니어링(Overkill)입니다.
  • 결과적 일관성 (Eventual Consistency): 물리적 분리 시 쓰기 모델의 변경 사항이 읽기 모델에 동기화되기까지 시간 지연(Latency)이 발생할 수 있습니다. 이로 인해 사용자가 방금 수정한 데이터를 즉시 보지 못하는 UX 문제가 발생할 수 있습니다.

🔗 Knowledge Connections

  • Event_Sourcing: CQRS와 짝을 이루어 상태 변경 내역을 이벤트 스트림으로 저장하고 읽기 모델을 구축하는 패턴입니다.
  • Domain_Driven_Design: 복잡한 도메인 로직을 구현하는 쓰기 모델(Command)을 설계할 때 기반이 되는 방법론입니다.
  • Hexagonal_Architecture: 비즈니스 코어에 영향을 주지 않고 읽기/쓰기 어댑터를 분리 장착할 수 있는 구조적 템플릿입니다.

Practical Application Contexts

  • High-Traffic Read Heavy Systems: 상품 상세 페이지나 SNS 타임라인처럼 조회 트래픽이 쓰기 트래픽보다 수백 배 많은 시스템.
  • Implementation: NestJS의 CQRS 모듈을 활용하여 CommandBus와 QueryBus로 트래픽 흐름을 제어합니다.

💡 Adjacent Topics

  • Microservices_Architecture: 각 마이크로서비스 내 데이터 일관성 한계를 극복하기 위해 CQRS와 이벤트를 통한 비동기 통신을 적극 차용합니다.
  • Event_Driven_Architecture: 모듈 간 횡단 관심사(cross-cutting)를 분리하고 메시지 브로커를 통해 이벤트를 파이프라인으로 연결합니다.

Last updated: 2026-05-02