이벤트 소싱과 CQRS: 이벤트 저장소를 선택할 때 따질 것
상태 변경을 순서 있는 이벤트로 남기는 이벤트 소싱과 명령·조회 모델을 분리하는 CQRS의 차이, 재생과 읽기 모델의 장점 및 복잡성 비용을 설명합니다.
발행·오류 제보: infostoa · 편집 기준
이 글의 개별 작성자와 전문 검토자 정보는 제공되지 않습니다.
현재 상태만 저장하는 대신 변경 사건을 순서대로 보존하면 과거 상태를 다시 계산하거나 조회 화면을 다른 형태로 만들 수 있습니다. 이것이 이벤트 소싱의 핵심입니다. CQRS는 쓰기 명령과 읽기 질의를 분리하는 설계이며, 이벤트 소싱과 함께 쓸 수 있지만 둘은 같은 패턴도 필수 묶음도 아닙니다.
현재 상태 대신 변경의 순서를 보존한다
일반적인 CRUD 모델은 주문의 현재 상태를 배송 중처럼 저장합니다. 이벤트 소싱에서는 주문 접수, 결제 승인, 상품 발송처럼 도메인에서 일어난 변경을 각각 기록하고, 이 순서에 따라 현재 상태를 계산합니다. 이벤트는 과거에 실제로 일어난 사실을 나타내므로, 이미 저장한 사건을 조용히 덮어쓰기보다 취소·정정 사건을 추가하는 편이 감사 추적과 시간별 상태 조회에 맞습니다.
다만 이벤트는 로그 문장이나 시스템 디버그 출력과 다릅니다. 애플리케이션의 상태 변경이 이벤트를 통해 이루어지고, 각 사건에 업무상 의미와 식별자, 발생 순서가 있어야 재생 가능한 기록이 됩니다. 어떤 필드를 이벤트에 넣을지, 개인 정보가 시간이 지나도 남아야 하는지, 오류를 어떻게 정정할지는 저장소 도입 전 정해야 할 데이터 수명주기 문제입니다.
이벤트 재생은 계산을 되살리지만 부작용까지 되풀이할 수 있다
저장된 이벤트를 처음부터 다시 적용하면 현재 상태를 재구성하거나 특정 시점의 상태를 조회할 수 있습니다. 새 읽기 화면이 필요할 때 과거 이벤트로 별도의 투영(projection)을 다시 만드는 것도 가능합니다. 이벤트가 많아지면 전체 재생은 느려질 수 있습니다. 그래서 현재 상태를 스냅샷으로 저장하고 스냅샷 이후의 이벤트만 적용하면 복구 계산량을 줄일 수 있습니다.
재생이 안전하려면 상태 계산과 외부 행동을 분리해야 합니다. 예를 들어 이벤트 처리 때마다 결제 요청이나 이메일 발송을 다시 실행하면 과거 이벤트를 읽는 과정이 실제 외부 거래를 중복 발생시킬 수 있습니다. 외부 호출의 기록·멱등성·중복 방지 규칙을 별도로 설계해야 하며, 이벤트 저장만으로 자동 해결되지는 않습니다.
CQRS는 읽기와 쓰기를 나누며 이벤트 소싱을 요구하지 않는다
CQRS(Command Query Responsibility Segregation)는 상태를 바꾸는 명령과 데이터를 읽는 질의를 서로 다른 모델로 다룹니다. 두 모델이 하나의 데이터베이스를 공유해도 CQRS가 될 수 있습니다. 읽기와 쓰기의 부하나 데이터 표현이 크게 다를 때 각각에 맞는 모델을 설계하면 이점이 생길 수 있습니다.
저장소까지 분리하면 쓰기 쪽의 이벤트를 읽기 모델의 투영으로 전달해야 합니다. 이때 읽기 화면이 잠시 이전 상태를 보여 주는 최종적 일관성, 메시지 중복·재시도, 데이터베이스와 브로커 사이의 원자성 문제가 생깁니다. Microsoft는 트랜잭셔널 아웃박스와 멱등 소비자 같은 완화책을 설명하지만, 이것들은 설계 요소이지 CQRS가 자동으로 보장하는 속성이 아닙니다. CQRS는 이벤트 소싱 없이도 쓸 수 있고, 이벤트 소싱도 단일 읽기 모델로 구현할 수 있습니다.
전문가 관점: 이벤트 이력의 가치가 운영 비용을 넘는 경우
업무 감사, 과거 시점 재구성, 새 읽기 화면의 반복 생성이 제품 요구사항이라면 이벤트 저장소의 이력이 유용할 수 있습니다. 반면 규칙이 단순하고 현재 값만 필요하다면 일반 CRUD가 운영과 팀 이해 측면에서 더 작고 직접적인 선택일 수 있습니다. 이벤트 스키마가 바뀔 때 과거 기록을 읽는 방법, 잘못된 사건의 보정, 재생 시간, 백업 복구, 보존·삭제 의무를 함께 계산해야 합니다.
Martin Fowler의 Event Sourcing 글은 2005년 12월 게시된 미완성 초안이며 페이지 자체가 후속 수정이 없었다고 밝힙니다. 따라서 이벤트 로그의 기본 아이디어와 재생·스냅샷의 설명에 참고하되, 최신 프레임워크 운영 지침으로 읽어서는 안 됩니다. Microsoft의 CQRS 설명은 명령·질의 분리와 별도 읽기 저장소의 일관성·복잡성 비용을 보완합니다. 핵심 판단은 “이벤트를 저장할 수 있는가”보다 “이력을 재구성해야 할 실제 업무가 있는가”입니다.