Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Info

스냅샷은 앞장 이벤트소싱에서도 부분적으로 사용이되었습니다. 스냅샷은 다양한곳에서 사용될수 있으며 그 컨셉은 간단합니다.

무수히 발생하는 이벤트로 인해 우리가 설계한 어떠한 객체의 상태는 지속적으로 변경된다는 점이며

복원관점에서 이벤트소싱이 과거 연속된 이벤트를 재생을 하여 상태를 복원하는 것이라고 하면복원하기위해 모든 이벤트자체를 모두 기록하는것과

모든 이벤트를 기록할필요없이 스냅샷은 특정시점의 상태를 복원하기위해, 주기적으로 상태를 원하는 만큼 저장하는 기능입니다.찍는 기능이 스냅샷입니다.

주로 게임 리플리와같이 게임시작부터 종료까지 게임플레이를 재생하려면 모든 이벤트를 기록해야 하는 반면

장바구니기능의 경우는 넣고빼고한 모든것을 기록할 필요없이 마지막 정보만 특정시점 저장을 하여 서비스에 활용될수 있습니다.

예를들어 한달전 라면+계란 장바구니를 이용한 사용자에게 금일 라면만 장바구니에 담는다고 하면 계란구매하는것을 잊은 사용자에게 그것을 추천하는 기능입니다.

  

모두를 기록해야하나? 특정시점을 기록해야하냐? 저장소(DB)를 포함하여 IT전반적으로 고민을하는 주제이며

주로 저장소의 한계와 성능의문제 때문에 적절하게 상호운영이 된다란 점이며 

아래의 검색 키워드를 통해서 그 차이를 파악할수가 있습니다. 보통 Redo와 Snapshot의 차이이며

여기서 오라클을 붙인다던지,  작업을 돌리는 redo task 를 붙인다던지 다양한 주제에 접근할수 있습니다.

연관 키워드 : difference between redo and snapshot 

스냅샷 구현

Code Block
final case class SnapshotMetadata(persistenceId: String, sequenceNr: Long, timestamp: Long = 0L)


private Object state;
private int snapShotInterval = 1000;

// 스냅샷을 지원하는 메시지 정의
@Override public Receive createReceive() {
  return receiveBuilder().
    match(SaveSnapshotSuccess.class, ss -> {
      SnapshotMetadata metadata = ss.metadata();
      // ...
    }).
    match(SaveSnapshotFailure.class, sf -> {
      SnapshotMetadata metadata = sf.metadata();
      // ...
    }).
    match(String.class, cmd -> {
      persist( "evt-" + cmd, e -> {
        updateState(e);
        if (lastSequenceNr() % snapShotInterval == 0 && lastSequenceNr() != 0)
          saveSnapshot(state);
      });
    }).build();
}

...