명령-질의 책임 분리(Command Query Responsibility Segregation, CQRS)은 마치 버즈워드처럼 이곳 저곳에 쓰이는 것 같아 언제 한 번 단어의 근본을 확실히 정리해야겠다고 생각하고 있었습니다. CQRS는 DBMS수준, 애플리케이션 소스코드 수준, API수준, 시스템 수준에서 모두 적용할 수 있기 때문에 그 단어를 사용하는 맥락도 함께 봐야 합니다.

블로그에 정리하려고 하다가 왠지 쎄해서 구글 스칼라에 검색해보니 이미 8년전에 누군가 석사논문으로 잘 정리해놨습니다. 심지어 공짜 (Nilsson, Korkmaz. “Practitioners’ View on Command Query Responsibility Segregation”, 2014년. http://lup.lub.lu.se/student-papers/record/4864802). 아래 내용은 논문에서 CQRS 관련 부분만 발췌해 적었습니다.

CQRS 이전에 CQS link
toc

버트란드 마이어는 1988년 CQS(Command Query Separation)를 제안했다. 1997년에 마이어는 CQS가 분산 컴퓨팅으로 이어질 수 있다(leads the way for distributed computation)고 했다. CQS는 1980년대에 나온 개념이지만 최근(2010년대 초)에 CQRS라는 이름으로 다시 부활(reincarnated)했다 (8쪽).

CQRS는 여러가지 의미를 지닐 수 있다. 아키텍처 스타일일 수도, 아키텍처 패턴일수도, 디자인 패턴일수도 있다. 여러가지 맥락에서 사용할 수 있는 단어다. 그러므로 CQRS는 추상적인 개념이라고 봐야 한다 (11쪽).

CQS는 객체수준의 디자인을 말한다 (클래스나 객체의 메서드). 1988년 마이어는 메서드를 함수Function와 프로시저Procedure라는 두 가지 타입으로 나누어야 한다고 제안했다 (13쪽).

  • 함수Function는 결과물을 생산하지만 상태에 영향을 주지 않는다.
  • 프로시저Procedure는 명백하게 상태에 영향을 주지만 결과물을 제공하지 않는다.

마이어는 1997년에 "질문하는 행위가 상태를 바꾸면 안된다"고 첨언했다 (13쪽).

CQRS의 탄생 link
toc

Kabbedijk, Jansen과 Brinkkemper(2013년)에 따르면 CQS와 DDD(Domain-Driven Development, 도메인 주도 개발)라는 두 가지 개념이 CQRS라는 용어의 탄생에 기여했다고 한다 (13쪽).

CQRS라는 단어는 2009년 언저리에 등장했지만 이 단어의 등장에 대한 합의(consensus)는 이루어지지 않았다. 2012년에 Fitzgerald는 CQRS를 정의했다: "애플리케이션이나 시스템의 책임을 쓰기Writing과 읽기Reading로 분리하는데, 객체 수준이 아니라 전체적인 아키텍처 수준에서 분리하는 것" (13쪽).

Fitzgerald는 CQRS와 CQS의 연관성을 CQRS의 정의에 분명하게Clearly 포함했다 (객체 수준=CQS). CQRS는 CQS를 객체 수준의 디자인이 아니라 애플리케이션 수준의 디자인에 채택한 것이다. 이는 아키텍처에 대해서 몇가지의 함의를 갖는다 (13쪽).

기업의 정보시스템은 보통 클라이언트-서버 아키텍처를 갖는다. 이런 시스템들은 탑-티어에 User Interface가, 반대편 티어에는 데이터베이스가 있다. 중간 티어들은 비즈니스 로직과 모델이다 (14쪽).

CQRS는 하나의 모델이 아니라 쿼리 모델과 커맨드 모델이라는 두 개의 모델을 제안한다. 커맨드 로직과 쿼리 로직을 나누어서 operator(Service layer를 말하는듯)의 복잡도를 낮출 수 있다. 이렇게 함으로써 CQRS는 CQS와 SRP(Single Responsibility Principle)을 따르게 된다 (14쪽).

한 클래스(커맨드 모델)는 생성, 갱신, 삭제를 담당하고 다른 하나는 읽기(쿼리 모델)를 담당한다. 이러한 책임의 분리는 데이터베이스까지 확장할 수 있다. 데이터베이스까지 CQRS를 확장한다면 커맨드용 DB와 쿼리용 DB를 나눔으로써 유사한 데이터가 두 곳에 존재하게 된다 (14쪽).

그리고 또 link
toc

여기까지가 15페이지까지의 내용이고, 뒤에는 Event Sourcing, Domain Driven Development, CAP 정리, Eventual Consistency, 정규화와 반정규화의 개념까지 나옵니다. 이 논문의 목적은 개념 정리가 아니고 CQRS의 효용성과 어려움에 대한 현직자들의 인터뷰이지만, 웹 백엔드 애플리케이션 개발에 중요한 개념들이 요약정리가 잘 되어있어서 단어에 대한 명확한 정의가 필요할 때 유용한 논문입니다.

논문의 결론 link
toc

논문에서 현직자 인터뷰를 통해 내린 결론은 다음과 같습니다:

CQRS가 사업팀과 개발팀간의 소통에도 도움이 되고 개발 측면에서도 Query부분과 Command부분을 분리해서 구현하므로 동시에 작업할 수 있다는 장점이 있지만, CQRS를 위해서는 필수로 코드의 모듈화가 선행되어야 하고 어쩔 수 없이 애플리케이션의 복잡도가 증가하는 것은 단점 (42쪽).

하지만 8년 전의 석사 논문이니 현시점에서 이 논문에 과도한 권위를 부여하면 안 되고, IT는 아직까지 학계보다 산업계의 진보가 빠른 점을 고려해야 합니다.

사족 link
toc

논문에선 CQRS를 top-level 아키텍처 디자인에 적용하는 것은 실수라고 여러번 얘기가 나옵니다. top-level 아키텍처 디자인이 무엇인지 논문에서 명확히 정의하지 않아서 아쉽습니다.

배달의민족은 Command와 Query를 시스템 수준에서 완전히 분리해 Query전용 백엔드 애플리케이션으로 무시무시한 트래픽을 감당하고 있습니다.