DevBoi

[DDD] axon framework를 사용해보자 (5) 본문

Develop/[DDD]

[DDD] axon framework를 사용해보자 (5)

HiSmith 2023. 6. 13. 20:49
반응형

공식 문서를 참조해서, 정리했다.

Event Bus, Event Store의 개념에 대해서 정리를 하고, 쿼리에 대한 개념을 정리해보자.

 

1) Event Store

Event를 읽고 쓰는데 있어, EventStore가 기본적으로 갖출 조건이 있다.

 

1. 이벤트는 추가만 가능하다, 입력 삭제,수정이 불가능하다.

2. 여러 이벤트가 하나의 트랜잭션에서 처리가 되어야 한다면, 트랜잭션 단위로 커밋,롤백 되어야한다.

3. 커밋된 이벤트는 유실되어서는 안된다.

4. 발행된 모든 Event중 Aggregate별로 데이터를 읽을 수 있어야 한다.

5. 모든 이벤트는 삽입된 순서대로 읽기가 가능해야한다.

6. Snapshot 저장소 지원

 

이벤트 저장소에, Aggregate에 대한 ID와 시퀀스 번호가 있다.

그리고 해당 이벤트저장소의 순서대로, 스냅샷 저장소로 가게 되고

해당 스냅샷 저장소의 순서대로, Command에서 처리가 된다.

처리가 된 이후에, 저장소에서는 다음 이벤트를 스냅샷 으로 보내고, 또 처리가 되는 방식이다.

 

7) Event Notification 기능

앱은 , 신규로 추가된 이벤트를 전파하지 못하면, 이벤트 전달이 불가하다

따라서, 수신 받고자하는 앱에서 주기적으로 해당 앱에 발생된 이벤트를 폴링해야한다.

따라서, 해당 과 같이, RDBMS로 이벤트 스토어를 두는것이 아니라,

카프카나 다른 메시지 큐를 이용해서 앱의 이벤트를 전달 하는방법이 있다.

하지만, 해당 메시지 큐를 거치다 보니, 트랜잭션이 깨질수 밖에 없고 데이터 동기화 측면에서 완벽을 보장할 수 없다.

또한 메시지 큐를 이용하다 보면 어쩔 수 없이 메시지 큐에 문제가 발생하는 상황이 생기고

해당 트랜잭션으로 묶이지 않기 떄문에, 당연하게 데이터 일관성도 깨진다.

 

axon 에서는 이벤트 버스로, 카프카로 사용할 수도 있는데, 해당과 같은 문제를 보장해주기 위해

메시지 전달 및 수신에 대한 핸들링 기능까지 제공한다.

따라서 가장 이상적인 구조는 Event Store 자체가 버스를 제공하는 것이 좋다.

 

 

1) RDBMS

트랜잭션에 대한 처리를 지원하는 강점이 있으나,

RDBMS는 데이터 처리량에 따라 속도가 급격하게 느려진다.

이유는, 데이터가 많아질 수록, 인덱스 및 B-tree구조상 깊이가 깊어질 수 밖에 없다.

해당 이유로 인해, 대량데이터 처리에 대한 이벤트 스토어로는 RDBMS는 적절하지않다.

또한 이벤트 알림에 대한 기능이 없다.

 

2) MongoDB

최신 몽고디비에서는 트랜잭션에 대한 지원해준다 (4.2부터는 MultiDocument에서, 단일노드에 한해 트랜잭션을 지원한다)

몽고 디비는 기본적으로 Wiredtiger 방식을 사용한다.

해당 저장 방식은 B-tree,컬럼 스토어,LSM이 있지만, 몽고는 아직 LSM을 지원하지 않는다. (LSM방식은 쓰기에 강하다, 이유는 나중에 포스팅)

이벤트 알림도 없다.

 

3)Kafka

이벤트 스트림을 전체를 다 읽어야 하기 때문에 EventSourcing에 있어서, 좋지 않다.

원하는 Aggregate를 필터링 하는작업을 소싱 때마다 반복해야한다.

 

 

대망의 Axon Server의 이벤트 Store 저장 방법이다.

 

Axon Server 내부에는 이벤트 저장을 위한 DB가 별도로 없다, 파일을 직접 다른다.

외부와의 연결은 Rest API혹은, gRPC 방법을 통해 가능하다.

EventStore는 오직 데이터 추가만이 가능하도록 설계가 되었다.

AxonServer에서는 EventStream을 일정 크기 별로 짤라서, Segment로 매핑한다.

각 Segment는 하나의 파일이고, 내부에는 EVENT가 연속적으로 할당되어있다.

생성된 파일은 데이터 corruption 확인을 위해 CRC체크 하여 파일 손상을 확인한다.

만약 Segment에 이벤트 엔트리가 가득차면, 새로운 파일을 생성하고 이를 가르키도록 인덱스정보를 추가한다.

EventStore는 스냅샷 저장소를 제공한다. 스냅샷 또한 세그먼트 단위로 저장되며

동일한 Aggregate의 번호가 매핑된 파일을 가르킨다.

자신의 Aggregate를 기준자로, 인덱스로 가르키기 떄문에, IO에서 좋은 성능을 제공한다.

AxonServer에서는 이러한 인덱스 포인트를 제공하기 위해 해당 필터를 제공한다.

 

Bloom FIlter

 

Bloom FIlter는 찾고자하는 데이터가 해당 집합에 포함되는지를 판단하는 확률적 자료구조이다.

DBMS에서 많이 사용하고, 디스크에서 찾고자하는 값이 존재할 가능성이 있을때만 블록을 읽는다.

 

 

 

위 그림으로 해당 과정을 보면, 쉽게 얘기해서, 비트에 대한 단위를 해시함수를 적용해서 찾는 값과 동일한지를 판별하고 읽는 것이다.

IO에 대한 작업이, 해당 해시 함수가 동일할떄 진행되기 때문에 불필요한 IO는 진행되지 않는다.

다만, 비트수가 너무 작다면 다른값임에도, 같은 해시함수값이 나올 수 있다.

해당 이유떄문에 Axonserver에서는, 비트를 많이 만들고, 해시함수 개수를 늘려, 최대한 불필요한 IO를 발생하지 않게 끔 해준다.

반응형