본문 바로가기

소프트웨어

[소프트웨어]CQRS(Command Query Responsibility Segregation)

참고 URL : javacan.tistory.com/564

 

CQRS 아는 척하기

CQRS(Command Query Responsibility Segregation) 아는 척하기1 영상: youtu.be/xf0kXMTFJm8 CQRS 아는 척하기 2 영상: youtu.be/H1IF3BUeFb8

javacan.tistory.com

오늘은 CQRS에 대해 정리를 해보도록 하겠습니다. 참고로 자료는 최범균님의 최신영상을 기초로 정리를 해봤습니다. 
CQRS라고 요즘 많이들 듣고 계실것 같은데요. 이게 무슨이야기인지 잘 모르시겠다고 생각하는 분만 보시면 되구요. 잘 아시는 분은 이것을 보실 필요는 없을것 같습니다.^^

우선은 축약된 단어의 뜻과 의미를 먼저 알아봅시다. 

CQRS 해석하면 : 명령 쿼리 역할 분담
    - 시스템의 역할에 맞게 분리하고 그에 맞는 구성요소를 배치하고, 데이터 수정/변경 및 조회를 처리 하도록 구현하기
C : Command(명령)
    - 데이터 수정 및 변경
    - 주문취소, 배송완료
Q : Query(조회) 
    - 데이터 조회
    - 주문 목록
R : Responsibility (역할+책임)
    - 구성 요소(클래스,함수,모듈,패키지,웹서버,DB)들의 역할과 책임이 존재
S : Segregation (분리)
    - 시스템을 각각의 역할에 맞게 분리하고, 그에 맞는 구성요소들을 배치하기
    - 코드를 나눌수도, 구현방식을 나눌수도, 데이터 베이스를 나눌수도, 프로세스를 나눌수도

정리하자면 CQRS는 시스템의 각각의 역할에 따라 분리하고 그에 맞는 구성요소들를 배치하고, 데이터 수정/변경 및 조회 처리하도록 구현하기 라고 생각하면 될것 같습니다. 아래 그림을 확인해보죠. 

CQRS의 예제 그림

위의 그림은 명령(command, 데이터 수정/변경)과 조회(Query, 데이터 조회)를 역할(Responsibility, 책임)에 따라 나누어(Segregatioin,분리) 구현한 그림입니다. 실제로 CQRS를 적용해서 구현한 아주 간단한 형태의 그림으로 한번 확인해 봤습니다. 하지만, 이 그림만으로는 CQRS를 왜 사용해야 하는지에 대한 이유를 찾기는 어렵기 때문에 이렇게 역할을 분리하지 않고, 단일 모델로 구현해보는 예제를 확인해 보죠.

단일 시스템으로 구현한 예시

단일 시스템으로 구현하게 될경우에는 위의 그림처럼 회원 목록 조회를 하게될 경우 Member가 반드시 가지고 있어야 할 것들이 아니라 부수적인 기능들이 들어가게 됩니다. 이럴경우 단순히 조회를 하려고 Member를 접근할 경우 오류가 발생할 수 있습니다. 

Member라는 코드의 역할이 그 객체가 가지고 있어야할 필수적인 내용이 아닌, 부가적인 내용들도 가지고 있기때문에 '회원 정보 조회'를 개발하는 사람 입장에서 이 부분을 접근하게되면, 부가된 데이터들을 더 처리해야 할 수 있겠죠. 그러면 원래 잘 되던 '회원 정보 조회'기능에서 발생하는 오류를 찾아서 반영하기 위해 어찌보면 필요없는 시간을 낭비해야 할 수 있습니다. 
이런 내용을 정릴해 보자면, 

이도저도 아닌 코드가 될 가능성이 높다.
- 코드의 역할/ 책임이 모호해 진다.
- 의미나 가독성등이 나빠진다.
- 유지보수 하기가 힘들어 진다.

이렇게 정리를 할 수 있을 것 같습니다.

여기에서 참고해야 할 부분은
명령(데이터 수정/변경)부분은 한 개 영역의 데이터 이고,
쿼리(데이터 조회)부분의 데이터는 여러개 영역의 데이터를 다루는 특성을 가진다는 것이다. 

명령과 쿼리는 코드 변경 빈도도 사용하는 사용자도 다릅니다. 코드 변경빈도가 다른 기능이 한 코드에 있게되면 서로 다른 이유로 코드가 바뀌게 됩니다. 이는 CQRS의 측면으로 볼때는 책임의 크기가 적당하지 않다고 봐야 할 것입니다.

또한, 기능마다 성능요구가 다릅니다. 기능마다 트래픽 패턴, 성능 요구가 다릅니다. 기능마다 서로다른 성능 향상 방법이 필요하구요. 단일 모델로는 다양한 성능 향상 기법을 적용하기가 어려울 수 있습니다.

하여, 명령과 쿼리를 구분하여 시스템을 구현한다고 보시면 되겠습니다.
결론은 아래 그림으로 정리를 하시면 될것 같네요, 좀 더 자세한 내용은 범균님 동영상으로 확인해보셔도 될것 같습니다.