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

Compare with Current View Page History

« Previous Version 8 Next »

스냅샷은 액터의 복구속도를 높일수가 있습니다.

SaveSnapShot을 호출하여 내부상태의 스냅샷을 저장할수가 있습니다.



액터설계

public class MySnapShotActor : UntypedPersistentActor
{
    private ILoggingAdapter log = Context.GetLogger();
    public override string PersistenceId => "my-stable-persistence-id";
    private const int SnapShotInterval = 2; //2의 배수에 스냅샷을 저장합니다.
    private object state = new object();

    //실시간 복구수 전략을 선택합니다. (최근5개)
    public override Recovery Recovery => new Recovery(fromSnapshot: new SnapshotSelectionCriteria(minSequenceNr:0, maxSequenceNr: 5, maxTimeStamp: DateTime.UtcNow));
    //public override Recovery Recovery => new Recovery(fromSnapshot: SnapshotSelectionCriteria.Latest);

    protected override void OnRecover(object message)
    {
        // handle recovery here
        if (message is SnapshotOffer offeredSnapshot)
        {
            log.Debug("마지막 스냅샷 복구");
            state = offeredSnapshot.Snapshot;
            log.Debug("스냅샷복구완료:" + state);
        }
        else if (message is RecoveryCompleted)
        {
            log.Debug("스냅샷복구완료:");
        }
        else
        {
            // event
            log.Debug("스냅샷e:" + message);
        }
    }

    protected override void OnCommand(object message)
    {
        if (message is SaveSnapshotSuccess s)
        {
            log.Debug("스냅샷 성공");
        }
        else if (message is SaveSnapshotFailure f)
        {
            log.Debug("스냅샷 실패");
        }
        else if (message is string cmd)
        {
            log.Debug("cmd:" + cmd);
            Persist($"evt-{cmd}", e =>
            {
                UpdateState(e);
                if (LastSequenceNr % SnapShotInterval == 0 && LastSequenceNr != 0)
                {
                    log.Debug("스냅샷 시도");
                    SaveSnapshot(state);
                }
            });
        }
    }

    private void UpdateState(string evt)
    {
        state = evt;
    }
}


Test 시나리오

  • 단순하게 문자열 메시지만 전송받습니다.
  • 액터가 종료되더라도 최근 50개의 메시지를 복구합니다.
  • 테스트코드에서는 100개의 메시지를 보내고 , 액터를 죽인후 다시 뛰워 복구가되는지 살펴봅니다.

var actorInfo = Props.Create<MySnapShotActor>();
var myactor = actorSystem.ActorOf(actorInfo, "myActor");
for(int i = 0; i < 5; i++)
{
    string message = "t" + i;
    myactor.Tell(message);
}

waitForTest(1000);
myactor.Tell(Akka.Actor.Kill.Instance, ActorRefs.NoSender);
waitForTest(1000);
//액터가 복구되는지 확인합니다.
myactor = actorSystem.ActorOf(actorInfo, "myActor");

......중간생략( 0-5까지 메시지 전송하고, 액터를 죽이고 다시살림)

...... 복구과정 ( 마지막 상태가 복구가됩니다. , 2의배수에서만 스냅샷 저장했으니, 3+1에해당하는 t3이 복구됩니다. )

[DEBUG][2017-09-25 오후 1:53:25][Thread 0025][[akka://ServiceA/user/myActor#1899122464]] 이전 스냅샷 복구
[DEBUG][2017-09-25 오후 1:53:25][Thread 0025][[akka://ServiceA/user/myActor#1899122464]] 스냅샷복구완료:evt-t3

위 테스트는 어플리케이션을 껏다가 켜도, 액터의 마지막 상태가 복원이 됩니다.

Store Plugin

스냅샷은 다양한 저장소에 저장이 가능하며,  akka.config에서 지정가능합니다.


설정예

akka.persistence.journal.inmem {
class = "Akka.Persistence.Journal.MemoryJournal, Akka.Persistence"
# Dispatcher for the plugin actor.
plugin-dispatcher = "akka.actor.default-dispatcher"
}

akka.persistence.snapshot-store.inmem {
# Class name of the plugin.
class = "Akka.Persistence.Snapshot.MemorySnapshotStore, Akka.Persistence"
# Dispatcher for the plugin actor.
plugin-dispatcher = "akka.actor.default-dispatcher"
}

akka.persistence.snapshot-store.local {
# Class name of the plugin.
}


별다른설정이없으면, 파일에 저장이 됩니다. 


참고 url : https://petabridge.com/blog/intro-to-persistent-actors/




  • No labels