CQRS (Command Query Responsibility Segregation)는 간단하게 표현하자면 읽기와 쓰기를 분리하여 처리하는 패턴이다.
쇼핑몰 주문 시스템이라고 가정하였을 때,
Command
Query
그런데 왜 분리를 해야 할까?
1. 확장성의 향상 & 성능 최적화
IT 플랫폼의 backend 쪽에서는 크게 2가지로 나누어 볼 수 있다. 읽기와 쓰기. 이 두 워크로드를 따로따로 스케일링이 가능한 장점이 있으며 코드 부분에서는 각각의 부분들을 특화된 구조로 가져갈 수도 있다.
2. 보안 및 권한 관리 용이
예를 들어, pod를 read와 write로 따로 분리하였다면 read pod는 read only db 계정을 가지고 작업할 수 있고 write pod는 write 권한이 들어간 db 계정으로 작업하면 된다. 조금 더 infra 적으로 들어간다면 istio 와 같은 service mash로 write db 또는 read only db로의 접근을 컨트롤 가능하며 이는 곧 보안이 더 강화된다는 말과 일맥상통한다.
3. 복잡한 도메인에 적합
DDD와 함께 사용하게 된다면 매우 세부적인 설계가 가능해진다.
1. 복잡성 증가
하나의 도메인에서도 쓰기와 읽기가 분리가 되기에 복잡성이 올라가게 된다. 특히나 db의 경우 write가 가능한 db와 read만 하게 되는 db를 나누어 사용한다면 인프라 관리 측면에서도 난이도가 올라간다.
2. 데이터의 일관성
예를 들어, 동일 데이터라도 관리를 위해 rdb, nosql에 다 넣지만, read model에서는 nosql만 접근할 수 있다. 수정이 있을 경후, rdb에 수정하고 추후 빠른 read를 위해 nosql에 새로 저장한뒤 object id를 다른곳에 넣어야 하는데, 만약 event driven 형태로 이 과정이 실행된다면 데이터가 다를 수 있다.
간단하게만 표현해본다면, 아래와 같이 표한할 수 있다.
내가 현재 서비스하고 있는 프로젝트도 위와 유사한 구조를 가지고 있다. 물론 위와 비교하였을 때, 중간에 스킵된 pod도 있고 저장되는 부분도 조금 다르긴 하지만 어느정도 선에서 CQRS를 따라가고 있다. 나중에 리펙토링 할 때 조금 더 디벨롭 할 부분이 많다.
위의 부분을 조금 글로써 설명해보자면,
Command
Query
가장 중요한 Tip,
CQRS는 정확한 분리와 비동기 흐름에 대한 이해가 핵심이다**
내가 진행하는 프로젝트는 CQRS를 조금 변형해서 사용하고 있다. 사실 SOT 자체가 외부에 있는 미들웨어 성격이 강하기에 어느정도 커스터마이징하여 사용하고 있는 중인데, 만약 올해 시간이 난다면 조금 더 다듬어 보고 싶다. 리펙토링 ㄱㅈㅇ