본문 바로가기
MSA

[MSA 3편] CQRS 정리

by 무대포 개발자 2022. 8. 3.
728x90
반응형

목차는 MSA 에 있습니다.

[MSA 3편] CQRS 정리

CQRS 란?

  • Command and Query Responsibility Segregation
  • 명령을 처리하는 책임과 조회를 처리하는 책임을 분리시키는 것입니다.

나오게 된 배경

  • 프로그램을 개발하다보면 도메인 모델의 복잡도가 증가하게 됩니다. 이는 유지보수성을 힘들게 하고, 요구사항이 추가될 때마다 변화에 유연하지 못합니다.
  • 하나의 Table 에 대해 각종 DTO 등이 점점 증가하게 되고 이를 해결하기 위해 CQRS 가 나왔습니다.

첫번째 사례

  • 동일한 Database 에 조회 하는 Model 과 CUD 하는 Model 을 분리하는 것입니다.
  • REST API 를 예로 들어보면 조회하는 Api 를 담당하는 controller 를 QueryController, CUD 를 담당하는 controller 를 CommandController 라고 만듭니다.
    • 각 controller, service 별로 사용하는 DTO 도 다릅니다.
  • 이렇게 작성하게 된다면 조회와 CUD 에 대한 api 를 분리하기에 유지 보수성이 편리해지고 요구사항이 추가되도 변화에 유연해질 수 있다고 할 수 있습니다.
  • 또한, spring 을 사용한다면 QueryService 쪽에 @Transactional(ReadOnly) 를 붙여 성능 향상을 쉽게 얻을 수 있습니다.

@RestController
@RequiredArgsConstructor
public class QueryController {
    private final QueryService xxx.
}


@RestController
@RequiredArgsConstructor
public class CommandController {
    private final CommandService xxx.
}
  • 하지만 이 패턴의 문제점은 동일한 데이터베이스를 사용하기에 성능상 문제점은 남아있습니다.
    • 여기서 말하는 성능상 문제점은 oracle 을 기준으로 인덱스를 사용한다고 가정했을 때, b+tree 알고리즘을 사용하게 됩니다.
    • B+TREE 알고리즘은 CUD 에 대한 성능은 안좋고 조회에 대한 성능은 좋습니다.

두번째 사례

  • database 까지 분리를 시키는 것이 두번째 사례입니다.
  • 예를 들면, MYSQL 의 Master, Slave 구조가 있습니다.
  • 위에 CommandController 는 Master db 를 붙도록 설정해 CUD 를 진행하고, QueryController 는 Slave DB 를 붙도록 설정해 조회를 제공합니다.
  • 단, 이 패턴은 두 DB 간의 동기화 처리를 위한 문제점을 해결해야만 합니다.
    • 위에서는 MySql 예제이지만 Master 가 RDB 이거나 Slave 가 NoSQL 일 수도 있습니다.

세번째 사례

  • 명령 시스템과 조회 시스템을 철저하게 분리합니다.
  • 데이터가 변경되는 부분을 따로 시스템으로 만들고, 데이터가 변경되면 조회 시스템에서 변경된 데이터를 가져갑니다.
    • Message Broker 나 Queue 를 통해 전달하면 시스템 간 결합도가 낮기에 좋습니다.
  • 조회 시스템에서는 해당 데이터를 가지고 반영을 합니다. (redis, Nosql 등)
    • 데이터를 읽는데 성능상 문제가 있다면 비정규화 데이터를 NoSQL 에 Key, Value 형식으로 저장을 합니다.
    • 예를 들면, 분산된 데이터들을 읽어와서 한줄로 데이터를 만들어 value 에 저장을 하고, key 를 통해 조회를 하는 것입니다.
    • 이렇게 하면 빠른 시간내에 조회가 가능해집니다.
  • 이렇게 구성한다면 데이터가 변경되는 부분과 조회하는 시스템이 분리되있기에 장애로부터 격리가 가능하며, 결합도가 낮습니다.

결론

  • CQRS 가 무조건 좋은 것은 아닙니다. 정말 간단한 시스템일 경우 이렇게 함으로서 오히려 더 복잡해질 수 있습니다. (CQRS 의 패턴대로 한다면)
  • API 내에 CRUD 뒤섞여있고 계속해서 소스가 변경될거 같다면 CQRS 를 고려해보는 것이 좋은 선택이 될 수 있을 것이라 생각합니다.

reference

'MSA' 카테고리의 다른 글

[MSA 5편] API Gateway Service 정리  (0) 2022.09.21
[MSA 4편] Service Discovery (Eureka)  (0) 2022.08.20
[MSA 2편] 보상 트랜잭션 (SAGA 패턴)  (2) 2022.06.11
[MSA 1편] MSA 기본 개념 정리  (0) 2022.06.11

댓글