You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 16 Next »

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

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

상태를 기록하는 범위주기에따라 세가지로 구분되며, 그 차이를통해 스냅샷을 이해할수가 있습니다.

  • 이벤트저장 : 상태복원은 연속된 이벤트 재생만을 통해가능하며 리플레이와같은 구현을 위해 이벤트 자체를 모두 기록해야하는것과
  • 상태 히스토리 저장 : 모든 이벤트를 기록할필요없이 특정시점의 상태를 복원을 하면되기 때문에, 원하는 만큼 사진을 찍는 스냡삽과 같은 기능이 필요합니다.
  • 마지막 상태만 저장 : 마지막 저장값만 보장함으로, 왜 변경되었고 바로 이전으로 돌리는것은 어렵습니다. 중앙DB를 이용한 일반적 개발 방식입니다.

범위가 넓고 주기가 짧을수록 성능을 고려해야하며, 스냅샷은 중간정도에 있는 저장 기능입니다.


연관 키워드 : difference between redo and snapshot


스냅샷 구현

@Component
@Scope("prototype")
public class SnapShotActor extends AbstractPersistentActor {
	
	private final LoggingAdapter log = Logging.getLogger(getContext().system(), "AbstractPersistentActor");	  
		
	private Object state;
	private int snapShotInterval = 5;
	
    @Override
    public String persistenceId() { return "ExamplePersistentActor-id-1"; }
    
    @Override public Receive createReceiveRecover() {
	  return receiveBuilder().
	    match(SnapshotOffer.class, s -> {
	      state = s.snapshot();	//상태복원
	      log.info("상태복원");
	      // ...
	    }).
	    match(String.class, s -> {/* ...*/}).build();
	}
	 
	// 스냅샷을 지원하는 메시지 정의
	@Override public Receive createReceive() {
	  return receiveBuilder().
	    match(SaveSnapshotSuccess.class, ss -> {
	      SnapshotMetadata metadata = ss.metadata();	      
	      // ...
	    }).
	    match(SaveSnapshotFailure.class, sf -> {
	      SnapshotMetadata metadata = sf.metadata();
	      // ...
	    }).
	    matchEquals("print", s -> System.out.println(state) ).	//마지막 상태확인	    
	    match(String.class, cmd -> {
	    	log.info("EventFired:"+cmd);	    	
	        if (lastSequenceNr() % snapShotInterval == 0 && lastSequenceNr() != 0)
		          //이벤트가 ?회 발생할때마다,상태를 변경하고 스냅샷을 찍음 ( 테스트를 위한 임의 조건)
	        	  log.info("SaveSnapShot");
	        	  state = "MyState" + cmd;
		          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)을 복원할수도 있습니다.


스냅샷 테스트

 




스냅샷 시도에따른 반응 메시지

MethodSuccessFailure message
saveSnapshot(Any)SaveSnapshotSuccessSaveSnapshotFailure
deleteSnapshot(Long)DeleteSnapshotSuccessDeleteSnapshotFailure
deleteSnapshots(SnapshotSelectionCriteria)DeleteSnapshotsSuccessDeleteSnapshotsFailure

스냅샷은 다양한 이유로(디스크풀및 메모리풀등) 실패가 있을수 있으며

그에 대응하는 코드작성도 가능합니다. 


다양한 활용 샘플 검색:



  • No labels