스냅샷은 앞장 이벤트소싱에서도 부분적으로 사용이되었습니다. 스냅샷은 다양한곳에서 사용될수 있으며 그 컨셉은 간단합니다.
무수히 발생하는 이벤트로 인해 우리가 설계한 어떠한 객체의 상태는 지속적으로 변경된다는 점이며
상태를 기록하는 범위와 주기에따라 세가지로 구분되며, 그 차이를통해 스냅샷을 이해할수가 있습니다.
- 상태복원은 연속된 이벤트 재생만을 통해가능하며 리플레이와같은 구현을 위해 이벤트 자체를 모두 기록해야하는것과
- 모든 이벤트를 기록할필요없이 특정시점의 상태를 복원을 하면되기 때문에, 원하는 만큼 사진을 찍는 스냡삽과 같은 장치입니다.
- 마지막 값 유지만 보장됨으로, 왜 변경되었고 바로 이전으로 돌리는것은 불가능합니다.
연관 키워드 : difference between redo and snapshot
스냅샷 구현
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(); }
스냅샷 저장에 필요한 메타정의(SnapshotMetadata) 후 자신이 원하는 타이밍에
카메라 셔터(saveSnapshot) 를 누르기만 하면됩니다.
스냅샷 복원
private Object state; @Override public Receive createReceiveRecover() { return receiveBuilder(). match(SnapshotOffer.class, s -> { state = s.snapshot(); // ... }). match(String.class, s -> {/* ...*/}).build(); } 또는 @Override public Recovery recovery() { return Recovery.create( SnapshotSelectionCriteria .create(457L, System.currentTimeMillis())); }
마지막 상태를 복원(SnapshotOffer)할수도 있고,
각 시간대별 스냅샷은 고유 아이디가 존재함으로
특정 스냅샷(SnapshotSelectionCriteria)을 복원할수도 있습니다.
스냅샷 시도에따른 반응 메시지
Method | Success | Failure message |
---|---|---|
saveSnapshot(Any) | SaveSnapshotSuccess | SaveSnapshotFailure |
deleteSnapshot(Long) | DeleteSnapshotSuccess | DeleteSnapshotFailure |
deleteSnapshots(SnapshotSelectionCriteria) | DeleteSnapshotsSuccess | DeleteSnapshotsFailure |
스냅샷은 다양한 이유로(디스크풀및 메모리풀등) 실패가 있을수 있으며
그에 대응하는 코드작성도 가능합니다.
다양한 활용 샘플 검색: