기술 노트

Event Sourcing(이벤트 소싱)에 대하여

Benn.dev 2022. 10. 25. 02:24

들어가며

it 업계의 막내들로서 함께 재밌게 스터디하고있는 친구들한테 접하게 된 키워드인데 생소한 내용이라 개념적으로나마 정리해보려고합니다.

차후에 팀에서 관련된 작업을 맡게되거나 도입을 고려할 때 조금 더 제가 쓸모있어지길 바라며 ㅎㅎ

 

개요

이벤트 소싱은 상태에 대한 변경 사항을 모두 저장하는 개발 패턴입니다.

이게 무슨 의미냐면 가령 서버개발을 할 때 DB에 연산이 된 결과값을 저장합니다.

하지만 이벤트 소싱은 순차적으로 발생하는 이벤트를 모두 저장합니다.

리팩터링 등의 유명한 책을 쓰신 마틴 파울러는 "애플리케이션의 모든 상태를 순서에 따라 이벤트로 보관"이라고 정의를 내리셨더라구요.

그럼 이벤트 소싱은 왜 쓸까요?

 

사용 목적

모든 갱신 이력 데이터를 저장해 해당 데이터를 통해 과서 상태로 회귀(재구성) 할 수 있기에 이 과정이 필요한 로직에 사용합니다.

로그와 유사한 점이 있다고 생각이 들지만 분명히 다른점도 존재하는데요,

제가 로그를 남기는 방식만 봐도 차이점이 존재합니다.

저는 보통 예외나 향후에 로그를 보고 문제 추적을 위한 각종 정보를 함께 남깁니다.

하지만 이벤트 소싱은 철저히 비즈니스 이벤트만 다루는 것이죠.

 

개념

이벤트 소싱은 삽입의 개념만 있습니다. 수정과 삭제라는 개념은 존재하지 않죠. 수정과 삭제라는 이벤트도 결국 수정과 삭제의 행위를 삽입 하는 겁니다. Append Only 이며 Immutable 할 수 있다고 볼 수 있습니다.

가령 Yes24의 주문 기능을 통해 봤을 때,

  1. 책을 장바구니에 담는다.
  2. 다른 책을 추가한다.
  3. 그 중 한 책을 제거한다.
  4. ...

이런 일련의 과정의 이벤트를 계속 적재하는겁니다.

하지만 이런 이벤트의 수가 점점 많아지면 최종 원하는 값을 얻기 위해선 많은 이벤트를 재생해야합니다.

예를들어 위의 이벤트가 100번까지 왔을 때 99번의 값을 얻기 위해선 1번부터 99번까지의 이벤트를 재생해야 얻을 수 있는 것입니다.

그래서 이벤트 소싱에서는 스냅샷의 개념이 있습니다.

 

구성

이벤트의 구성은 다음과 같습니다.

event identifier(aggregate id)
event type
event version
time
payload

여기서 aggregate 는 관련 도메인을 하나의 군집으로 묶은 것입니다. 

이렇게 구성된 이벤트들은 모두 순차적으로 영구적인 저장소에 보관됩니다.

주로 이벤트 저장소로는 File System, NoSQL, RDBMS 등 영구적으로 보관할 수 있는 기능을 제공해주는 시스템에 저장합니다.

 

장점과 단점

이벤트 소싱 방식의 장점은 다음과 같습니다.

  • 저장소의 확장에 용이합니다. 저장소라는건 결국 용량이 다 찰수도 있어 언젠가는 확장을 염두해야 하는데요, 데이터 분할을 위한 유일한 키는 해당 집합체의 식별자이기 때문에 확장에 용이합니다. 샤딩해서 관리하면 될 것 같습니다.
  • 도메인 이벤트를 수정하기 위한 수정과 삭제 기능이 없기 때문에 데이터의 접근을 위한 경쟁이 없습니다. 그래서 항상 골치아픈 동시성이슈에 자유롭습니다.
  • 성능도 저장 연산만 존재하기 때문에 심플하다고 볼 수 있습니다. 이걸 성능이 좋다고 표현해야 할까요?

이벤트 소싱 방식의 단점은 다음과 같습니다.

  • 조회 요구에 적합하지 않습니다. 가령 100개의 이벤트가 저장되어있는데 현재 상태를 알기 위해서는 매번 100개의 이벤트를 리플레이 해야합니다. 또 이는 저장된 이벤트 수에 비례해 리플레이 시간이 증가되게 됩니다. 하지만 이를 보완하기 위해 스냅샷이라는 개념과 CQRS라는 개념이 존재합니다.
  • 단순 모델이면 배보다 배꼽이 더 커질 우려가 있습니다. 굳이 이벤트 소싱 방식이 아니여도 충분히 해당 비즈니스를 풀어갈 수 있다면 사용할 필요가 없어보입니다.

그럼 지금껏 나온 스냅샷이라는 개념은 무엇일까요?

 

스냅샷

스냅샷은 이벤트 식별자(event identifier = aggregate id), 이벤트 버전, 리플레이된 도메인 객체로 구성됩니다.

이벤트 식별자를 통해 조회하며 이를 통해 리플레이된 도메인 객체를 바로 뽑아 사용할 수 있어 앞서 설명드린 100번의 리플레이 과정이 필요없게 됩니다.

스냅샷은 이벤트 저장소와 분리된 저장소에 저장하고 인메모리 솔루션 같은 가급적 성능이 좋은 저장소를 사용합니다.

 

전체적인 이벤트 소싱 흐름

  1. Request (command object create + validation)
  2. Command handler
  3. Query 인 경우: Aggregate 생성 ► 이벤트 저장소에서 이벤트 조회 ► 스냅샷 조회 & 병합 ► 이벤트 리플레이
  4. Command 인 경우: 이벤트 저장소에서 이벤트 저장 ► 스냅샷 저장소에서 스냅샷 저장

 

마치며

이벤트 소싱에 대해 개념적으로나마 간단하게 작성해봤습니다. 오늘은 개념에 대해 잊지 않으려 메모해두지만 다음에 더 깊게 공부할 수 있는 기회가 있으면 좋겠네요. 더 찾아보고 싶으시면 아래 링크를 참고해주세요.

https://learn.microsoft.com/ko-kr/azure/architecture/patterns/event-sourcing

 

이벤트 소싱 패턴 - Azure Architecture Center

추가 전용 저장소를 사용하여 도메인의 데이터에 대해 수행된 작업을 설명하는 일련의 이벤트 전체를 기록합니다.

learn.microsoft.com


레퍼런스 1