본문 바로가기
MSA

[MSA] Event Sourcing 이란?

by 개발자건빵 2022. 8. 7.

Event Sourcing 이란 ?

이벤트 소싱이란 application의 모든 상태를 일으키는 이벤트를 순서에 맞게 저장하여 status를 만들어내는 방법입니다. 먼저 말씀 드리면 사실 일반적인 경우에 필요하진 않습니다. 아니, 대부분의 경우에는 이렇게 구현할 필요하가 없습니다. 하지만 필요한 경우가 있고 장점도 충분히 가지고 있습니다. 설계할 때 몰라서 고려하지 않는 것 보다는 알아두면 좋은 설계 테크닉 정도로 생각하시면 좋을것 같습니다.

먼저 일반적으로 어플리케이션에서 데이터 모델을 저장하는 방법은 현재 상태를 저장하는 방법을 이용합니다. 여기에는 NoSQL, RDBMS 등을 따지지 않습니다. 어떤 데이터를 어떤 모델로 저장하냐에 대한 부분입니다. 이렇게 저장했을 때는 우리는 마지막 상태값만을 알 수 있습니다. 만약 log를 남기는 테이블을 주고 snapshot을 찍었다면 우리는 지금까지 원하는 데이터의 변화되어온 상태를 알 수 있게 될 것입니다. 하지만 이러한 저장 방식으로는 현재 상태가 된 why(이유) 또는 how(방법)을 알 수 없습니다. 우리는 데이터의 상태를 알 수 있을 뿐입니다.

이벤트 소싱은 위애 정의한 듯이 데이터의 상태를 변경시키는 모든 데이터를 저장합니다. 그리고 사용할 때 이를 replay 해서 데이터의 마지막 상태값을 만들어 냅니다. 정의를 보면 이벤트를 저장한다고 했는데 이것은 제가 보기엔 상태를 만들어내는 Command를 저장한다고 보면 될 것 같습니다. 이렇게 저장했을 때의 장점은 기존 데이터 모델에서는 알 수 없었던 현재 상태가 된 why(이유)를 Event 데이터와 이를 replay했을 때 바로 알 수 있다는 것입니다.

그렇다면 아래에서 이벤트 소싱에 대해 더 자세한 이야기를 해보도록 하겠습니다.

Example of Event Sourcing

위에서 Event Sourcing에 대해서 설명했지만 좀 더 이해를 돕기 위해서 예를 하나 들어보도록 하겠습니다. 아래 예제는 Axon 사이트에서 나와있던 예제를 이미지화 한 것입니다. 일반적인 데이터 저장 방식과 이벤트 소싱 저장방식은 아래 와 같은 차이를 가집니다.

이미지에서 박스 1개가 RDBMS에서의 row 1개에 해당한다고 봐주시면 될 것 같습니다.

특이점으로 보면 2번째 콜라 선택을 했을 때와 4번째 감자튀김 제거를 했을 때 일반적인 데이터 저장 방식으로는 동일한 값을 가지는 것을 알 수 있습니다. 같은 상태를 가지지만 이는 다른 방식으로 해당 상태가 되었다는 사실을 우리는 이미지로 알 수 있습니다. 반면에 이벤트 소싱을 이용한 오른쪽 데이터를 보도록 하겠습니다. row 수는 상대적으로 많다는 것을 알 수 있습니다. 하지만 데이터를 통해 해당 상태가 된 이유를 설명할 수 있다는 장점을 가진다는 것을 이해할 수 있었습니다.


장점

Event Sourcing의 가장 눈에 특징은 Object의 모든 상태 변화가 기록되어진다는 것에 있습니다. 그러면 이렇게 Event Sourcing 기법을 통한다면 어떠한 장점을 가질 수 있는 지 먼저 알아보도록 하겠습니다.

  • History : 모든 상태 변화가 기록하기때문에 이는 Application과의 상호작용(interaction) 로그(History)로써 활용
  • Complete Rebuild : Object의 Event Sourcing를 처음부터 replay하면 현재 상태로 완벽하게 재현 가능
  • Temporal Query : 현재 상태 뿐만 아니라 Object의 특정 시점으로 replay 가능
  • Event Replay : 만약 비즈니스 로직이 잘못되어있어서 문제가 발생했다면 비즈니스 수정 후 Event를 reversing & replay하여 정상화 가능
    • 단, 외부 의존성을 판단하여 충분히 사용할 수 있고 유효한 방법일 지 확인 필요
  • 애자일 방식으로 개발을 진행할 때 기존 event 데이터를 통해서 로직이 정상인지 검증 가능
  • Admin 시스템 등이라면 full audit 기능이 필요하며 이 기능의 log로 활용 가능
  • 경우에 따라 Write( Create / Update / Delete ) Operation의 속도의 상승으로 latency 최소화 ( Event를 저장 후 이후 후처리를 하는 방식 채택을 통해 )

단점

장점을 알아보았으니 이번에는 단점을 알아보도록 하겠습니다.

  • 현재 정확한 정보를 얻기 위해서는 Event Soucring의 Event 데이터를 replay 해야하므로 read 성능 약화
    • snapshot을 통해 어느정도 완화할 수 있지만 동일 기존 모델에 비해서는 떨어짐
  • 대부분 Eventually Consistency를 기본으로 하기 때문에 유저의 write 성공한다고 바로 유저가 최신 정보를 얻을 수 없을 수 있음
  • 기존 모델에 비해서 상대적으로 데이터 저장을 더 많이 하기 때문에 대용량 데이터 처리에 대한 고민이 필요
  • write에 대한 고민이 줄어드는 대신 read에 대한 고민이 늘어남
    • 어떻게 데이터를 유저에게 빠르게 보여줄 수 있을 것인가 ?
    • read 모델과 write 모델의 불일치에 따른 CQRS 고민 필요

CQRS와 Event Sourcing의 관계

위의 단점에서 살짝 언급했습니다만 Event Sourcing은 read 모델과 write 모델이 다르기 때문에 CQRS의 장점과 단점을 그대로 가질 수 밖에 없습니다. 즉, Event Sourcing은 CQRS가 없이는 이루어 질 수 없다고 보시는게 좋을것 같습니다. 

 

사용할 수 있는 예제

Event Sourcing을 사용할 수 있고 장점을 활용할 수 있는 예제는 사실 그렇게 많지 않습니다. 활용하면 좋을것으로 보이는 예시로 아래를 들 수 있습니다.

  • 어플리케이션 Object 상태 저장소 ( 상태 변화를 모두 저장해야하느 경우 )
  • Audit 저장소
    • 유저의 행위를 모두 기록하는 저장소
  • Event Reversing & Replay가 필요한 경우
    • Event의 재발행이 불가능한 시스템
  • 재화 시스템을 만들 경우 해당 재화의 전체 흐름을 파악하기 위한 시스템
    • ex) 미국의 Sarbanes–Oxley Act 법 대응 시스템

카프카와 이벤트 소싱, CQRS

결론부터 말하자면 카프카는 이벤트 소싱 패턴과 CQRS 패턴을 적용한 애플리케이션에 적용 가능하고 효과적으로 동작합니다. 카프카 스트림즈 라이브러리를 사용하면 애플리케이션에서 이벤트 소싱 패턴과 CQRS 패턴을 구현할 수 있습니다. 카프카 스트림즈는 카프카 클러스터와 연동할 수 있는 자바 라이브러리로서 토픽의 데이터를 처리(프로세스)하고 다시 토픽으로 데이터를 저장하는데 특화되어 있습니다. 뿐만 아니라 토픽에 존재하는 스트림 데이터(또는 언바운디드 데이터, 끝이 없는 데이터)를 스트림단위, 테이블 단위로 조회하고 처리할 수 있습니다. 카프카의 내부 구조(파티션 단위 등)에 맞게 동작하기 때문에 높은 확장성, 고 가용성, 분산처리 등의 특징을 지니고 있습니다.

 

스트림즈를 구현하면 이벤트 소싱과 CQRS로 구현된 아키텍처를 카프카 기반으로 변경할 수 있다. 

이벤트 소싱, CQRS로 구현된 애플리케이션들

스트림즈를 통해 이벤트 핸들러를 구현

 

각각의 애플리케이션에 구체화된 뷰(Materialized View)를 만들어 이벤트 소싱 패턴과 CQRS 패턴을 구현한 모습

 

반면에 카프카를 이벤트 소싱, CQRS로 사용하는 것에 대해 의구심을 가지는 의견도 있다. 토픽이라는 단위는 이벤트의 고유한 ID기반으로 생성할 수 없으며 해당 ID의 종료에 대한 대응(특정 이벤트 삭제)한 기능이 없기 때문에 적합하지 않다고 한다. 

 

참고 문헌

[1] https://www.baeldung.com/cqrs-event-sourcing-java

[2] https://www.baeldung.com/axon-cqrs-event-sourcing

[3] https://martinfowler.com/eaaDev/EventSourcing.html

[4] https://developer.axoniq.io/event-sourcing/overview

'MSA' 카테고리의 다른 글

[MSA] Saga 패턴을 통한 분산DB 트랜잭션  (0) 2022.09.27
[Spring] Event Driven (우아콘2020)  (0) 2022.08.21
Event Driven Architecture 란?  (0) 2022.07.28
MSA 아키텍처  (0) 2022.07.06

댓글