Programming

[CQRS 아는 척하기] CQRS 구현 형태

nineDeveloper 2021. 1. 5. 16:43
728x90

https://www.youtube.com/watch?v=H1IF3BUeFb8&list=PLwouWTPuIjUgr29uSrSkVo8PRmem6HRDE&index=4

 

CQRS(Command Query Responsibility Segregation)

구현 형태

  • 명령과 쿼리 모델이 한 프로세스에 있는지 다른 프로세스에 있는지
  • 같은 DB를 사용하는지 다른 DB를 사용하는지


구현: 같은 프로세스, 같은 DB

  • 가장 단순
  • 명령/쿼리 동일 데이터 보장


구현: 같은 프로세스, 같은 DB, 다른 테이블

명령과 쿼리가 코드 수준에서 분리 되고 데이터 수준에서도 분리되는 방식
단 데이터가 같은 DB에 있는 형태

  • 쿼리 전용 테이블 사용
    • 예: 최근 조회수 많은 글 목록을 별도 테이블로 따로 저장
    • 쿼리 모델은 이 테이블을 이용해서 구현
  • 명령이 상태를 변경할때 쿼리 전용 테이블을 함께 변경


구현: 같은 프로세스, 다른 DB

  • 예: 상품목록을 레디스와 같은 저장소에 캐싱하고 쿼리 모델은 레디스를 사용하는 방식
    • 명령이 데이터를 변경하면 변경내역을 쿼리쪽 DB에 전달


구현: 다른 프로세스, 다른 DB

  • 명령이 데이터를 변경하면 변경내역을 쿼리쪽 DB에 전달
    • 마이크로서비스 분리 추세에 따라 많이 만날 수 있는 형태


다른 DB로 변경 전파

  • 명령이 직접 쿼리 DB를 수정하는 방식
    • 카프카와 같은 메세징 수단을 이용해서 전달하는 변형도 있음
    • 장점: 구현이 단순함
    • 단점: 데이터 유실 가능성이 있음
      • 쿼리 DB나 메시징이 일시적으로 장애가 발생하게 되면 쿼리 DB에 반영해야 할 데이터가 유실될 수 있음
      • 쿼리 DB나 메시징의 문제 때문에 명령을 수행하는 기능 자체가 에러가 발생할 수 있음
  • 변경내역을 기록하고 별도 전파기를 이용해서 변경내역을 전달하는 방식
    • 중간에 메시징을 두는 변형이 있음
    • 명령은 상태를 변경한 다음 변경내역을 별도 테이블에 기록 함
    • 장점: 한 트랜잭션으로 처리 되기 때문에 변경내역이 유실되지 않음
    • 단점: 전파기를 별도로 구현해야하는 부담이 있음
  • DB가 제공하는 CDC를 사용하는 방식
    • 중간에 메시징을 두는 변형이 있음
    • DB의 바이너리 로그를 읽어서 변경 데이터를 확인하고 변경된 데이터를 쿼리쪽에 전달하는 방식
    • 장점: 명령 쪽 코드에서 변경내역을 따로 저장하지 않아도 되므로 명령코드가 단순해짐


다른 DB 사용시 주의 사항

  • 데이터 유실
    • 유실 허용 여부에 따라 DB 트랜잭션 범위 중요
      • 주문목록 쿼리 기능의 경우 데이터가 유실되면 곤란함
      • 최근 읽기글 쿼리 기능은 일시적으로 데이터 전파가 안되도 치명적이지 않음
  • 허용 가능 지연 시간
    • 명령의 변경내역을 얼마나 빨리 쿼리쪽에 반영하는지에 따라서 구현의 선택이 달라질 수 있음
  • 중복 전달
    • 쿼리쪽 DB에 변경된 데이터를 전달하는 과정에서 문제가 발생하게 되면 다시 전달할 수 있는 수단이 필요
    • 다시 전달할 수 있는 수단을 만들다 보면 쿼리쪽에 이미 반영된 데이터를 중복으로 전달하는 경우도 발생하게 됨
    • 중복으로 데이터를 전달 하더라도 쿼리쪽 데이터가 망가지지 않도록 별도의 처리를 해야 함

참고자료


정리

시스템이 복잡해질 수록 시스템이 오래 유지보수 될수록 유리해짐

  • 명령과 쿼리는 다루는 데이터가 다름
  • 명령과 쿼리는 코드 변경 빈도/사용자가 다름
  • 기능마다 성능 요구가 다름
728x90