안정적인 대용량 트래픽 처리가 가능한 티켓팅 서비스 - 설계(3) [CQRS]

jj J·2023년 2월 13일
1

Spring

목록 보기
3/5

이전 설계 2편에 이어 해당 편은 도입 검토중인 CQRS에 대해서 알아본 것을 정리하고 어떤 형태로 적용할지 결정하려 한다.

CQRS : Command Query Responsibility Segregation

명령(시스템 데이터 변경) 역할을 수행하는 구성 요소와 쿼리(시스템 데이터 조회) 역할을 수행하는 구성 요소를 나누는 것.

명령

  • 시스템 데이터 변경
  • 기능 : 주문취소, 배송완료 등

쿼리

  • 시스템 데이터 조회
  • 기능 : 주문 목록 등

RS : Responsibility Segregation

책임

  • 구성 요소의 역할
  • 구성 요소
    • 클래스, 함수
    • 모듈/패키지
    • 웹서버/DB

분리

  • 역할에 따라 구성 요소 나누기

CQRS가 필요한 경우

명령과 조회에 단일 모델을 사용하면?

단점

  • 코드 역할/책임 모호
  • 의미/가독성 등 나빠짐
  • 유지보수성이 떨어짐
  • 즉시/지연 로딩 적용 기준 모호해짐

단점이 발생하는 이유

  • 명령과 쿼리는 다루는 데이터가 다름
    • 명령 : 한 영역의 데이터
    • 쿼리 : 여러 영역의 데이터

  • 명령과 쿼리는 코드 변경 빈도, 사용자 다름
    • 예시 : 백오피스의 주문 목록 조회 기능, 사용자의 주문 기능
    • 변경 빈도가 다른 기능이 한 코드에 있으면
      • 서로 다른 이유로 코드가 바뀌고
      • 이는 곧 책임의 크기가 적당하지 않다는 것
  • 기능마다 성능 요구가 다름
    • 기능마다 트래픽 패턴, 성능 요구 다름
      • 사용자 상품 목록 조회, 상품 상세 조회
      • 댓글 등록
      • 주문
      • 백오피스 판매 수치 등
    • 기능마다 서로 다른 성능 향상 방법 필요
      • 단일 모델로는 다양한 성능 향상 기법 적용이 어려울 수 있음

구현 형태 예시

1. 같은 프로세스, 같은 DB

  • 가장 단순
  • 명령/쿼리 동일 데이터 보장
  • 코드 수준에서만 분리

2. 같은 프로세스, 같은 DB, 다른 테이블

  • 쿼리 전용 테이블 사용
    • 예 : 최근 조회수 많은 글 목록
  • 명령 수행 시 쿼리 전용 테이블 까지 변경함

3. 같은 프로세스, 다른 DB

  • 명령 수행 후 변경 내역을 쿼리 DB로 전파함

4. 다른 프로세스, 다른 DB

  • 3번과 동일하나 다른 프로세스에서 진행
  • MSA에서 주로 사용되는 방식

다른 DB로 변경 전파

1. 명령이 직접 쿼리 DB를 수정하는 방식

  • 카프카같은 메시징 큐로 전달하는 변형도 있음
  • 장점 : 구현이 단순
  • 단점 : 데이터 유실 가능성이 있음
    • 쿼리 DB나 메시징이 일시적으로 문제 발생하게 되면, 쿼리 DB에 반영되야 할 데이터가 유실되거나, 쿼리 DB나 메시징의 문제때문에 명령 수행 기능 자체가 에러 날 수 있음

2. 변경 내역을 기록하고, 별도 전파기를 이용해서 내역을 전달하는 방식

  • 1번과 마찬가지로 중간에 메시징 큐를 두는 변형도 있음
  • 장점 : 변경을 진행하고 그 내역을 별도 테이블에 저장함, 이 과정은 한 트랙잭션으로 처리되기때문에 변경 내역이 유실되지 않음
  • 단점 : 전파기를 따로 구현해야됨

3. DB가 제공하는 CDC 이용

  • 메시징 큐 변형 존재
  • DB 바이너리 로그를 읽어서 데이터를 확인하고, 그 데이터를 쿼리 DB에 전달
  • 장점 : 2번과 비슷하나 명령쪽에서 내역을 따로 저장하지 않아도 되니, 코드가 단순해진다.

다른 DB 사용 시 주의 사항

- 데이터 유실

- 유실 허용 여부에 따라 DB 트랜잭션 범위 중요
- 예 : 주문 목록은 유실되면 절대 안됨, 최근 인기글은 일시적으로 안되도 치명적이진 않음

- 허용 가능 지연 시간

- 명령의 변경 내역을 얼마나 빨리 쿼리쪽에 반영시켜야하는가에 따라 구현 선택이 달라질 수 있음

- 중복 전달

- 쿼리쪽 DB에 변경 데이터를 전달하는 과정에서, 문제가 생기면 다시 전달할 수 있는 수단이 필요, 그 과정에서 쿼리쪽에 이미 반영된 데이터를 중복 전달하는 경우도 발생할 것.
- 중복 전달하더라도 쿼리쪽 데이터가 망가지지않도록 별도 처리가 필요함

출처 : https://martinfowler.com/bliki/CQRS.html
https://www.youtube.com/watch?v=H1IF3BUeFb8
https://www.youtube.com/watch?v=xf0kXMTFJm8

profile
매일 발전

0개의 댓글