Gestione dello stato di Reliable ActorsReliable Actors state management

I Reliable Actors sono oggetti a thread singolo che possono incapsulare sia la logica che lo stato.Reliable Actors are single-threaded objects that can encapsulate both logic and state. Poiché gli attori vengono eseguiti nei servizi Reliable Services, possono mantenere lo stato in modo affidabile con gli stessi meccanismi di persistenza e replica utilizzati da Reliable Services.Because actors run on Reliable Services, they can maintain state reliably by using the same persistence and replication mechanisms that Reliable Services uses. In questo modo, gli attori non perdono il proprio stato dopo gli errori, dopo la riattivazione in seguito a un'operazione di garbage collection o quando vengono spostati tra i nodi di un cluster a causa del bilanciamento delle risorse o degli aggiornamenti.This way, actors don't lose their state after failures, upon reactivation after garbage collection, or when they are moved around between nodes in a cluster due to resource balancing or upgrades.

Replica e persistenza dello statoState persistence and replication

Tutti i Reliable Actors vengono considerati con stato perché ogni istanza dell'attore è mappata a un ID univoco.All Reliable Actors are considered stateful because each actor instance maps to a unique ID. Ciò significa che le chiamate ripetute allo stesso ID attore vengono instradate alla stessa istanza dell'attore.This means that repeated calls to the same actor ID are routed to the same actor instance. In un sistema senza stato invece le chiamate client non vengono instradate ogni volta necessariamente allo stesso server.In a stateless system, by contrast, client calls are not guaranteed to be routed to the same server every time. Per questo motivo, i servizi Actor sono sempre servizi con stato.For this reason, actor services are always stateful services.

Anche se gli attori sono considerati con stato, non significa che devono archiviare lo stato in modo affidabile.Even though actors are considered stateful, that does not mean they must store state reliably. Gli attori possono scegliere il livello di replica e persistenza dello stato in base ai requisiti di archiviazione dei dati:Actors can choose the level of state persistence and replication based on their data storage requirements:

  • Stato persistente: lo stato è persistente nel disco e viene replicato in almeno tre repliche.Persisted state: State is persisted to disk and is replicated to 3 or more replicas. Questa è l'opzione di archiviazione dello stato più durevole, in cui lo stato può persistere anche in caso di interruzione di un cluster completo.This is the most durable state storage option, where state can persist through complete cluster outage.
  • Stato volatile: lo stato viene replicato in almeno tre repliche e viene mantenuto solo in memoria.Volatile state: State is replicated to 3 or more replicas and only kept in memory. Fornisce la resilienza in caso di errore del nodo, di errore dell'attore e durante gli aggiornamenti e il bilanciamento delle risorse.This provides resilience against node failure and actor failure, and during upgrades and resource balancing. Lo stato tuttavia non è persistente nel disco.However, state is not persisted to disk. Perciò, se vengono perse contemporaneamente tutte le repliche, si perderà anche lo stato.So if all replicas are lost at once, the state is lost as well.
  • Stato non persistente: lo stato non viene replicato né viene scritto su disco.No persisted state: State is not replicated or written to disk. Questo livello è appropriato per gli attori che non devono mantenere lo stato affidabile.This level is for actors that simply don't need to maintain state reliably.

Ogni livello di persistenza è semplicemente un altro provider di stato e un'altra configurazione di replica del servizio.Each level of persistence is simply a different state provider and replication configuration of your service. La scrittura su disco dello stato dipende dal provider di stato, ovvero il componente di un servizio Reliable Services che archivia lo stato.Whether or not state is written to disk depends on the state provider--the component in a reliable service that stores state. La replica dipende dal numero di repliche con cui viene distribuito un servizio.Replication depends on how many replicas a service is deployed with. In modo analogo ai servizi Reliable Services, il provider di stato e il numero di repliche possono essere impostati manualmente con facilità.As with Reliable Services, both the state provider and replica count can easily be set manually. Il framework per gli attori fornisce un attributo che, quando viene usato in un attore, seleziona automaticamente un provider di stato predefinito e genera automaticamente le impostazioni per il numero di repliche in modo da ottenere una di queste tre impostazioni di persistenza.The actor framework provides an attribute that, when used on an actor, automatically selects a default state provider and automatically generates settings for replica count to achieve one of these three persistence settings. L'attributo StatePersistence non viene ereditato dalla classe derivata e ogni tipo di attore deve specificare il proprio livello StatePersistence.The StatePersistence attribute is not inherited by derived class, each Actor type must provide its StatePersistence level.

Stato persistentePersisted state

[StatePersistence(StatePersistence.Persisted)]
class MyActor : Actor, IMyActor
{
}
@StatePersistenceAttribute(statePersistence = StatePersistence.Persisted)
class MyActorImpl  extends FabricActor implements MyActor
{
}

Questa impostazione usa un provider di stato che archivia i dati su disco e imposta automaticamente il numero di repliche del servizio su 3.This setting uses a state provider that stores data on disk and automatically sets the service replica count to 3.

Stato volatileVolatile state

[StatePersistence(StatePersistence.Volatile)]
class MyActor : Actor, IMyActor
{
}
@StatePersistenceAttribute(statePersistence = StatePersistence.Volatile)
class MyActorImpl extends FabricActor implements MyActor
{
}

Questa impostazione usa un provider di stato solo in memoria e imposta il numero di repliche su 3.This setting uses an in-memory-only state provider and sets the replica count to 3.

Stato non persistenteNo persisted state

[StatePersistence(StatePersistence.None)]
class MyActor : Actor, IMyActor
{
}
@StatePersistenceAttribute(statePersistence = StatePersistence.None)
class MyActorImpl extends FabricActor implements MyActor
{
}

Questa impostazione usa un provider di stato solo in memoria e imposta il numero di repliche su 1.This setting uses an in-memory-only state provider and sets the replica count to 1.

Impostazioni predefinite e impostazioni generateDefaults and generated settings

Quando si usa l'attributo StatePersistence, viene selezionato automaticamente un provider di stato in fase di esecuzione all'avvio del servizio attore.When you're using the StatePersistence attribute, a state provider is automatically selected for you at runtime when the actor service starts. Il numero di repliche, tuttavia, viene impostato in fase di compilazione dagli strumenti di compilazione dell'attore di Visual Studio.The replica count, however, is set at compile time by the Visual Studio actor build tools. Gli strumenti di compilazione generano automaticamente un servizio predefinito per il servizio attore in ApplicationManifest.xml.The build tools automatically generate a default service for the actor service in ApplicationManifest.xml. I parametri vengono creati per le dimensioni minime del set di repliche e le dimensioni del set di repliche di destinazione.Parameters are created for min replica set size and target replica set size.

È possibile cambiare questi parametri manualmente.You can change these parameters manually. Tuttavia, ogni volta che l'attributo StatePersistence viene modificato, i parametri vengono impostati sui valori predefiniti delle dimensioni del set di repliche per l'attributo StatePersistence selezionato, eseguendo l'override di eventuali valori precedenti.But each time the StatePersistence attribute is changed, the parameters are set to the default replica set size values for the selected StatePersistence attribute, overriding any previous values. In altri termini, l'override dei valori impostati in ServiceManifest.xml viene eseguito solo in fase di compilazione quando si modifica l'attributo StatePersistence.In other words, the values that you set in ServiceManifest.xml are only overridden at build time when you change the StatePersistence attribute value.

<ApplicationManifest xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" ApplicationTypeName="Application12Type" ApplicationTypeVersion="1.0.0" xmlns="http://schemas.microsoft.com/2011/01/fabric">
   <Parameters>
      <Parameter Name="MyActorService_PartitionCount" DefaultValue="10" />
      <Parameter Name="MyActorService_MinReplicaSetSize" DefaultValue="3" />
      <Parameter Name="MyActorService_TargetReplicaSetSize" DefaultValue="3" />
   </Parameters>
   <ServiceManifestImport>
      <ServiceManifestRef ServiceManifestName="MyActorPkg" ServiceManifestVersion="1.0.0" />
   </ServiceManifestImport>
   <DefaultServices>
      <Service Name="MyActorService" GeneratedIdRef="77d965dc-85fb-488c-bd06-c6c1fe29d593|Persisted">
         <StatefulService ServiceTypeName="MyActorServiceType" TargetReplicaSetSize="[MyActorService_TargetReplicaSetSize]" MinReplicaSetSize="[MyActorService_MinReplicaSetSize]">
            <UniformInt64Partition PartitionCount="[MyActorService_PartitionCount]" LowKey="-9223372036854775808" HighKey="9223372036854775807" />
         </StatefulService>
      </Service>
   </DefaultServices>
</ApplicationManifest>

State ManagerState manager

Ogni istanza dell'attore ha un proprio gestore di stato: una struttura di dati simile a un dizionario che archivia in modo affidabile le coppie chiave-valore.Every actor instance has its own state manager: a dictionary-like data structure that reliably stores key/value pairs. Il gestore di stato è un wrapper per il provider di stato.The state manager is a wrapper around a state provider. Può essere usato per archiviare i dati indipendentemente dall'impostazione di persistenza utilizzata.You can use it to store data regardless of which persistence setting is used. Non garantisce assolutamente che un servizio attore in esecuzione possa essere modificato da un'impostazione di stato volatile (solo in memoria) in un'impostazione di stato persistente tramite un aggiornamento in sequenza mantenendo al tempo stesso i dati.It does not provide any guarantees that a running actor service can be changed from a volatile (in-memory-only) state setting to a persisted state setting through a rolling upgrade while preserving data. Tuttavia, è possibile modificare il numero di repliche per un servizio in esecuzione.However, it is possible to change replica count for a running service.

Le chiavi di gestione dello stato devono essere stringhe.State manager keys must be strings. I valori sono di tipo generico e possono essere di qualsiasi tipo, inclusi i tipi personalizzati.Values are generic and can be any type, including custom types. I valori archiviati nel gestore di stato devono essere serializzabili in base al contratto dati perché possono essere trasmessi in rete ad altri nodi durante la replica e possono essere scritti su disco, a seconda dell'impostazione di persistenza dello stato di un attore.Values stored in the state manager must be data contract serializable because they might be transmitted over the network to other nodes during replication and might be written to disk, depending on an actor's state persistence setting.

Il gestore di stato espone i metodi di dizionario comuni per la gestione dello stato, simili a quelli disponibili in Reliable Dictionary.The state manager exposes common dictionary methods for managing state, similar to those found in Reliable Dictionary.

Accesso allo statoAccessing state

Lo stato è accessibile tramite il gestore di stato mediante la chiave.State can be accessed through the state manager by key. I metodi del gestore di stato sono tutti asincroni perché possono richiedere operazioni di I/O del disco quando gli attori hanno uno stato persistente.State manager methods are all asynchronous because they might require disk I/O when actors have persisted state. Al primo accesso, gli oggetti di stato vengono memorizzati nella cache.Upon first access, state objects are cached in memory. Le operazioni di accesso ripetute accedono agli oggetti direttamente dalla memoria e vengono restituite in modo sincrono senza incorrere nel sovraccarico di operazioni di I/O del disco o di cambio di contesto asincrono.Repeat access operations access objects directly from memory and return synchronously without incurring disk I/O or asynchronous context-switching overhead. Un oggetto di stato viene rimosso dalla cache nei casi seguenti:A state object is removed from the cache in the following cases:

  • Il metodo di un attore genera un'eccezione non gestita dopo il recupero di un oggetto dal gestore di stato.An actor method throws an unhandled exception after it retrieves an object from the state manager.
  • Un attore viene riattivato dopo essere stato disattivato o dopo un errore.An actor is reactivated, either after being deactivated or after failure.
  • Il provider di stato invia lo stato al disco.The state provider pages state to disk. Questo comportamento dipende dall'implementazione del provider di stato.This behavior depends on the state provider implementation. Il provider di stato predefinito per l'impostazione Persisted ha questo comportamento.The default state provider for the Persisted setting has this behavior.

Lo stato può essere recuperato con un'operazione Get standard che genera l'eccezione KeyNotFoundException(C#) o NoSuchElementException(Java) se non esiste una voce per la chiave:You can retrieve state by using a standard Get operation that throws KeyNotFoundException(C#) or NoSuchElementException(Java) if an entry does not exist for the key:

[StatePersistence(StatePersistence.Persisted)]
class MyActor : Actor, IMyActor
{
    public MyActor(ActorService actorService, ActorId actorId)
        : base(actorService, actorId)
    {
    }

    public Task<int> GetCountAsync()
    {
        return this.StateManager.GetStateAsync<int>("MyState");
    }
}
@StatePersistenceAttribute(statePersistence = StatePersistence.Persisted)
class MyActorImpl extends FabricActor implements  MyActor
{
    public MyActorImpl(ActorService actorService, ActorId actorId)
    {
        super(actorService, actorId);
    }

    public CompletableFuture<Integer> getCountAsync()
    {
        return this.stateManager().getStateAsync("MyState");
    }
}

Lo stato può essere recuperato anche con un metodo TryGet che non genera alcuna eccezione se non esiste una voce per la chiave:You can also retrieve state by using a TryGet method that does not throw if an entry does not exist for a key:

class MyActor : Actor, IMyActor
{
    public MyActor(ActorService actorService, ActorId actorId)
        : base(actorService, actorId)
    {
    }

    public async Task<int> GetCountAsync()
    {
        ConditionalValue<int> result = await this.StateManager.TryGetStateAsync<int>("MyState");
        if (result.HasValue)
        {
            return result.Value;
        }

        return 0;
    }
}
class MyActorImpl extends FabricActor implements  MyActor
{
    public MyActorImpl(ActorService actorService, ActorId actorId)
    {
        super(actorService, actorId);
    }

    public CompletableFuture<Integer> getCountAsync()
    {
        return this.stateManager().<Integer>tryGetStateAsync("MyState").thenApply(result -> {
            if (result.hasValue()) {
                return result.getValue();
            } else {
                return 0;
            });
    }
}

Salvataggio dello statoSaving state

I metodi di recupero del gestore di stato restituiscono un riferimento a un oggetto nella memoria locale.The state manager retrieval methods return a reference to an object in local memory. Se questo oggetto viene modificato solo nella memoria locale non verrà salvato in modo permanente.Modifying this object in local memory alone does not cause it to be saved durably. Quando un oggetto viene recuperato dal gestore di stato e modificato, deve essere reinserito nel gestore di stato per essere salvato in modo permanente.When an object is retrieved from the state manager and modified, it must be reinserted into the state manager to be saved durably.

Lo stato può essere inserito usando un metodo Set non condizionale, che è l'equivalente della sintassi dictionary["key"] = value:You can insert state by using an unconditional Set, which is the equivalent of the dictionary["key"] = value syntax:

[StatePersistence(StatePersistence.Persisted)]
class MyActor : Actor, IMyActor
{
    public MyActor(ActorService actorService, ActorId actorId)
        : base(actorService, actorId)
    {
    }

    public Task SetCountAsync(int value)
    {
        return this.StateManager.SetStateAsync<int>("MyState", value);
    }
}
@StatePersistenceAttribute(statePersistence = StatePersistence.Persisted)
class MyActorImpl extends FabricActor implements  MyActor
{
    public MyActorImpl(ActorService actorService, ActorId actorId)
    {
        super(actorService, actorId);
    }

    public CompletableFuture setCountAsync(int value)
    {
        return this.stateManager().setStateAsync("MyState", value);
    }
}

È possibile aggiungere lo stato tramite il metodo Add.You can add state by using an Add method. Questo metodo genera l'eccezione InvalidOperationException(C#) o IllegalStateException(Java) se si tenta di aggiungere una chiave già esistente.This method throws InvalidOperationException(C#) or IllegalStateException(Java) when it tries to add a key that already exists.

[StatePersistence(StatePersistence.Persisted)]
class MyActor : Actor, IMyActor
{
    public MyActor(ActorService actorService, ActorId actorId)
        : base(actorService, actorId)
    {
    }

    public Task AddCountAsync(int value)
    {
        return this.StateManager.AddStateAsync<int>("MyState", value);
    }
}
@StatePersistenceAttribute(statePersistence = StatePersistence.Persisted)
class MyActorImpl extends FabricActor implements  MyActor
{
    public MyActorImpl(ActorService actorService, ActorId actorId)
    {
        super(actorService, actorId);
    }

    public CompletableFuture addCountAsync(int value)
    {
        return this.stateManager().addOrUpdateStateAsync("MyState", value, (key, old_value) -> old_value + value);
    }
}

È possibile aggiungere lo stato anche con il metodo TryAdd.You can also add state by using a TryAdd method. Questo metodo non genera eccezioni se si tenta di aggiungere una chiave già esistente.This method does not throw when it tries to add a key that already exists.

[StatePersistence(StatePersistence.Persisted)]
class MyActor : Actor, IMyActor
{
    public MyActor(ActorService actorService, ActorId actorId)
        : base(actorService, actorId)
    {
    }

    public async Task AddCountAsync(int value)
    {
        bool result = await this.StateManager.TryAddStateAsync<int>("MyState", value);

        if (result)
        {
            // Added successfully!
        }
    }
}
@StatePersistenceAttribute(statePersistence = StatePersistence.Persisted)
class MyActorImpl extends FabricActor implements  MyActor
{
    public MyActorImpl(ActorService actorService, ActorId actorId)
    {
        super(actorService, actorId);
    }

    public CompletableFuture addCountAsync(int value)
    {
        return this.stateManager().tryAddStateAsync("MyState", value).thenApply((result)->{
            if(result)
            {
                // Added successfully!
            }
        });
    }
}

Alla fine di un metodo di un attore, il gestore di stato salva automaticamente tutti i valori che sono stati aggiunti o modificati da un'operazione di inserimento o aggiornamento.At the end of an actor method, the state manager automatically saves any values that have been added or modified by an insert or update operation. Un'operazione di salvataggio può includere il salvataggio su disco in modo permanente e la replica, a seconda delle impostazioni usate.A "save" can include persisting to disk and replication, depending on the settings used. I valori che non sono stati modificati non vengono salvati in modo permanente né replicati.Values that have not been modified are not persisted or replicated. Se non è stato modificato alcun valore, l'operazione di salvataggio non eseguirà alcuna azione.If no values have been modified, the save operation does nothing. Se il salvataggio non riesce, lo stato modificato verrà eliminato e verrà ricaricato lo stato originale.If saving fails, the modified state is discarded and the original state is reloaded.

Lo stato può anche essere salvato manualmente chiamando il metodo SaveStateAsync sulla base dell'attore:You can also save state manually by calling the SaveStateAsync method on the actor base:

async Task IMyActor.SetCountAsync(int count)
{
    await this.StateManager.AddOrUpdateStateAsync("count", count, (key, value) => count > value ? count : value);

    await this.SaveStateAsync();
}
interface MyActor {
    CompletableFuture setCountAsync(int count)
    {
        this.stateManager().addOrUpdateStateAsync("count", count, (key, value) -> count > value ? count : value).thenApply();

        this.stateManager().saveStateAsync().thenApply();
    }
}

Rimozione dello statoRemoving state

Lo stato può essere rimosso in modo permanente dal gestore di stato di un attore chiamando il metodo Remove.You can remove state permanently from an actor's state manager by calling the Remove method. Questo metodo genera l'eccezione KeyNotFoundException (C#) o NoSuchElementException(Java) se si tenta di rimuovere una chiave che non esiste.This method throws KeyNotFoundException(C#) or NoSuchElementException(Java) when it tries to remove a key that doesn't exist.

[StatePersistence(StatePersistence.Persisted)]
class MyActor : Actor, IMyActor
{
    public MyActor(ActorService actorService, ActorId actorId)
        : base(actorService, actorId)
    {
    }

    public Task RemoveCountAsync()
    {
        return this.StateManager.RemoveStateAsync("MyState");
    }
}
@StatePersistenceAttribute(statePersistence = StatePersistence.Persisted)
class MyActorImpl extends FabricActor implements  MyActor
{
    public MyActorImpl(ActorService actorService, ActorId actorId)
    {
        super(actorService, actorId);
    }

    public CompletableFuture removeCountAsync()
    {
        return this.stateManager().removeStateAsync("MyState");
    }
}

È possibile rimuovere in modo permanente lo stato anche con il metodo TryRemove.You can also remove state permanently by using the TryRemove method. Questo metodo non genera eccezioni se si tenta di rimuovere una chiave che non esiste.This method does not throw when it tries to remove a key that does not exist.

[StatePersistence(StatePersistence.Persisted)]
class MyActor : Actor, IMyActor
{
    public MyActor(ActorService actorService, ActorId actorId)
        : base(actorService, actorId)
    {
    }

    public async Task RemoveCountAsync()
    {
        bool result = await this.StateManager.TryRemoveStateAsync("MyState");

        if (result)
        {
            // State removed!
        }
    }
}
@StatePersistenceAttribute(statePersistence = StatePersistence.Persisted)
class MyActorImpl extends FabricActor implements  MyActor
{
    public MyActorImpl(ActorService actorService, ActorId actorId)
    {
        super(actorService, actorId);
    }

    public CompletableFuture removeCountAsync()
    {
        return this.stateManager().tryRemoveStateAsync("MyState").thenApply((result)->{
            if(result)
            {
                // State removed!
            }
        });
    }
}

Passaggi successiviNext steps

Lo stato archiviato in Reliable Actors deve essere serializzato prima di essere scritto sul disco e replicato per la disponibilità elevata.State that's stored in Reliable Actors must be serialized before its written to disk and replicated for high availability. Altre informazioni sulla serializzazione del tipo di attore.Learn more about Actor type serialization.

Vedere anche Diagnostica e monitoraggio delle prestazioni per Reliable Actors.Next, learn more about Actor diagnostics and performance monitoring.