헬창 개발자

CQRS 패턴 본문

공부방

CQRS 패턴

찬배 2026. 2. 25. 10:54

1. CQRS란 무엇인가?

CQRS(Command Query Responsibility Segregation)는 단어 그대로 명령(Command)과 조회(Query)의 책임(Responsibility)을 분리(Segregation)하는 아키텍처 패턴입니다.

 

 
  • Command (명령): 시스템의 상태를 변경하는 작업 (Create, Update, Delete). 반환 값은 성공 여부나 ID 정도이며, 상태 정보를 반환하지 않는 것을 원칙으로 합니다.
  • Query (조회): 시스템의 상태를 반환하는 작업 (Read). 데이터를 변경하지 않으며, 오직 조회된 결과만을 반환합니다.

2. 왜 CQRS가 필요한가?

일반적인 CRUD 중심의 아키텍처에서는 저장소에 데이터를 넣을 때 쓰는 모델과 화면에 보여주기 위해 가공된 모델이 일치하지 않는 경우가 많습니다.

  1. 조회 최적화의 한계: 복잡한 Join 연산이나 다중 필터링이 필요한 조회 로직이 쓰기 로직과 섞여 있으면, 성능 최적화(인덱싱, 캐싱 등)가 어려워집니다.
  2. 도메인 로직의 오염: 읽기 성능을 위해 비즈니스 로직이 담긴 엔티티에 조회용 필드를 추가하다 보면, 도메인 모델이 점점 복잡해지고 유지보수가 힘들어집니다.
  3. 트래픽 불균형: 실제 서비스 트래픽의 90% 이상은 '조회'입니다. 쓰기와 읽기를 분리하지 않으면, 조회 트래픽 폭주 시 쓰기 성능까지 함께 영향을 받게 됩니다.

3. CQRS 구현 단계

CQRS는 반드시 DB를 쪼개야 하는 것은 아닙니다. 시스템의 복잡도에 따라 단계별로 적용할 수 있습니다.

Step 1. 코드 레벨의 분리

 

하나의 DB를 공유하지만, 소스 코드 내에서 명령 서비스와 조회 서비스를 명확히 분리합니다.

  • Command: 도메인 로직을 수행하고 트랜잭션을 관리합니다.
  • Query: DAO나 단순 SQL 호출을 통해 DTO를 반환하는 데 집중합니다.

Step 2. 데이터베이스의 분리

 
 

Write 전용 DB(Master)와 Read 전용 DB(Slave)를 두어 물리적인 부하를 분산합니다.

  • Write DB: 데이터의 무결성을 위해 정규화된 형태를 유지합니다.
  • Read DB: 조회 성능을 위해 반정규화하거나 전용 인덱스를 설정합니다.

Step 3. 저장소 파이프라인 분리 (이벤트 소싱)

 

쓰기에는 RDBMS를, 조회에는 Elasticsearch나 Redis 같은 NoSQL을 사용하는 극단적 최적화 단계입니다.

  • 쓰기 발생 시 이벤트(Event)를 발행하고, 이를 구독하는 프로세스가 조회용 저장소의 데이터를 업데이트합니다.

참고

https://www.popit.kr/cqrs-eventsourcing/

https://rudaks.tistory.com/entry/%EC%84%B1%EB%8A%A5-%ED%8C%A8%ED%84%B4-CQRS-%ED%8C%A8%ED%84%B4

https://junuuu.tistory.com/891