[MSA] CQRS

CQRS 정리

Why?

  • UX, 비즈니스 요구 사항 복잡할 때
  • 조회 성능을 보다 높이고 싶을 때
  • 데이터 관리 영역 / 뷰 전달 영역 책임 분리
  • 시스템 확장성 높이고 싶을 때

CQRS 사용하는 경우

  • 여러 모델, 다양한 종류의 데이터베이스에 저장된 동일한 데이터와 작동할 필요가 있는 애플리케이션에 유용
  • 이벤트 소싱 도메인 모델

What is CQRS?

Command-Query Responsibility Segregation

여러 서비스에 있는 데이터를 가져오는 쿼리는 이벤트를 이용하여 해당 서비스의 데이터를 복제한 읽기 전용 뷰를 유지한다.
이벤트 소싱 모델의 질의 한계 극복 목적에서 시작됨. 허나 이벤트 소싱이 아니더라도 유용할 수 있음

모델의 분리

1) 커맨드 실행 모델

시스템의 상태를 수정하는 오퍼레이션 전담 수행 단일 모델

  • 비즈니스 로직 구현, 규칙 검사, 불변성 강화

2) 읽기 모델(프로젝션)

사용자에게 데이터를 보여주거나 다른 시스템에 정보를 제공하기 위해 필요한 모델 정의

  • 캐시에서 언제든 다시 추출 가능 프로젝션
    • DB, 파일, 인메모리 캐시에 위치 가능
  • 읽기 전용 : 읽기 모델의 데이터 직접 수정 불가
  • RDB의 Materialized view와 비슷한 개념

프로젝션 생성 두 가지 방식

  1. 동기식
    • 격차 해소 구독 모델 활용 OLTP 데이터 변경사항 가져옴
  2. 비동기식
    • 커맨드 실행 모델은 모든 커밋된 변경사항을 메시지 버스에 발행
    • 주의점
      • 메시지 순서 오류 또는 중복 처리 시 읽기 모델에 일관성 없는 데이터 프로젝션 가능성 존재
      • => 가능하면 동기식 프로젝션 방식 구현, 그 위에 선택적으로 비동기식 프로젝션 방식 추가 권장

모델분리

  • 커맨드 : 강한 일관성을 가진 커맨드 실행 모델에서만 동작
  • 질의 : 읽기 모델과 커맨드 실행 모델을 포함하여 그 어떤 시스템의 영속 상태 직접 수정 불가
  • 대부분의 경우 커맨드는 데이터를 반환 : 불필요한 데이터 왕복 발생 X
    • 단점 : 반환 데이터가 커맨드에서 비롯됨. 이렇게 되면 프로젝션에 대해 즉각적인 갱신 기대하기 어려움.

How?

변경 감지 방법

  • JPA EntityListeners
    • @Entity / @MappedSuperclass 객체 메소드 : 어노테이션 지정 사용 가능
    • 콜백 지정 함수 선언 가능 : @PrePersist, @PostPersist, @PreUpdate, … 등 7가지
    • @EntityListeners 어노테이션과 함께 callback listener class 구현 가능
    • 해당 엔티티만 인자로 반환 => 엔티티 특정 속성 변경 추적 어려움
  • Hibernate EventListener
    • SessionFactoryImpl -> SessionFactoryServiceRegistry -> EventListenerRegistry
    • 26가지 콜백 유형
    • 받고자 하는 상황에 따른 인터페이스 구현 클래스 등록
    • 상세한 정보 전달 (변경 프로퍼티, 이전 상태, 현재 상태 등)
    • 모든 엔티티 변경 사항 전달
  • Hibernate Interceptor
    • Session, SessionFactory에 Interceptor 등록
    • 인터셉터이기 때문에 저장될 데이터 조작 가능
  • Spring AOP
    • 메서드에만 설정 가능
    • 변경 감지에 있어서 복잡도 높아질 수 있음
  • CDC?

참조