Serializzazione di un oggetto Reliable Collections in Azure Service FabricReliable Collection object serialization in Azure Service Fabric

Le raccolte Reliable Collections replicano e mantengono i propri elementi per garantirne la persistenza anche in caso di errori del computer o interruzioni dell'alimentazione.Reliable Collections' replicate and persist their items to make sure they are durable across machine failures and power outages. Per replicare e rendere persistenti gli elementi, le raccolte Reliable Collections devono serializzarli.Both to replicate and to persist items, Reliable Collections' need to serialize them.

Le raccolte Reliable Collections ottengono il serializzatore appropriato per un determinato tipo da Reliable State Manager.Reliable Collections' get the appropriate serializer for a given type from Reliable State Manager. Reliable State Manager contiene serializzatori predefiniti e consente la registrazione di serializzatori personalizzati per un determinato tipo.Reliable State Manager contains built-in serializers and allows custom serializers to be registered for a given type.

Serializzatori predefinitiBuilt-in Serializers

Reliable State Manager include serializzatori predefiniti per alcuni tipi comuni, così da consentirne una serializzazione efficiente per impostazione predefinita.Reliable State Manager includes built-in serializer for some common types, so that they can be serialized efficiently by default. Per altri tipi, Reliable State Manager esegue il fallback per l'uso di DataContractSerializer.For other types, Reliable State Manager falls back to use the DataContractSerializer. I serializzatori predefiniti risultano più efficienti perché sanno che i loro tipi non possono essere modificati e non hanno bisogno di includere informazioni sul tipo quali il nome.Built-in serializers are more efficient since they know their types cannot change and they do not need to include information about the type like its type name.

Reliable State Manager dispone di un serializzatore predefinito per i tipi seguenti:Reliable State Manager has built-in serializer for following types:

  • GuidGuid
  • boolbool
  • bytebyte
  • sbytesbyte
  • byte[]byte[]
  • charchar
  • stringstring
  • decimaldecimal
  • doubledouble
  • floatfloat
  • intint
  • uintuint
  • longlong
  • ulongulong
  • shortshort
  • ushortushort

Serializzazione personalizzataCustom Serialization

I serializzatori personalizzati vengono comunemente usati per migliorare le prestazioni o per crittografare i dati in rete e su disco.Custom serializers are commonly used to increase performance or to encrypt the data over the wire and on disk. Tra le altre ragioni, i serializzatori personalizzati sono in genere più efficienti dei serializzatori generici poiché questi non devono serializzare le informazioni sul tipo.Among other reasons, custom serializers are commonly more efficient than generic serializer since they don't need to serialize information about the type.

IReliableStateManager.TryAddStateSerializer viene usato per registrare un serializzatore personalizzato per un tipo T specificato. Questa registrazione deve avvenire durante la costruzione di StatefulServiceBase per assicurare che, prima dell'avvio del ripristino, tutte le raccolte Reliable Collections abbiano accesso al serializzatore pertinente per leggere i dati resi persistenti.IReliableStateManager.TryAddStateSerializer is used to register a custom serializer for the given type T. This registration should happen in the construction of the StatefulServiceBase to ensure that before recovery starts, all Reliable Collections have access to the relevant serializer to read their persisted data.

public StatefulBackendService(StatefulServiceContext context)
  : base(context)
  {
    if (!this.StateManager.TryAddStateSerializer(new OrderKeySerializer()))
    {
      throw new InvalidOperationException("Failed to set OrderKey custom serializer");
    }
  }

Nota

I serializzatori personalizzati hanno la precedenza su quelli predefiniti.Custom serializers are given precedence over built-in serializers. Ad esempio, quando viene registrato un serializzatore personalizzato per int, tale serializzatore viene usato per serializzare i valori integer al posto del serializzatore predefinito per int.For example, when a custom serializer for int is registered, it is used to serialize integers instead of the built-in serializer for int.

Come implementare un serializzatore personalizzatoHow to implement a custom serializer

Un serializzatore personalizzato deve implementare l'interfaccia IStateSerializer.A custom serializer needs to implement the IStateSerializer interface.

Nota

IStateSerializer include un overload per Write e Read che accetta un T aggiuntivo chiamato valore di base.IStateSerializer includes an overload for Write and Read that takes in an additional T called base value. Questa API è per la serializzazione differenziale.This API is for differential serialization. Attualmente la funzionalità di serializzazione differenziale non è esposta.Currently differential serialization feature is not exposed. Di conseguenza, questi due overload non vengono chiamati fino a quando la serializzazione differenziale non è esposta e abilitata.Hence, these two overloads are not called until differential serialization is exposed and enabled.

Di seguito è riportato un esempio di un tipo personalizzato denominato OrderKey che contiene quattro proprietàFollowing is an example custom type called OrderKey that contains four properties

public class OrderKey : IComparable<OrderKey>, IEquatable<OrderKey>
{
    public byte Warehouse { get; set; }

    public short District { get; set; }

    public int Customer { get; set; }

    public long Order { get; set; }

    #region Object Overrides for GetHashCode, CompareTo and Equals
    #endregion
}

Di seguito è riportato un esempio di implementazione di IStateSerializer.Following is an example implementation of IStateSerializer. Si noti che gli overload Write e Read che accettano baseValue chiamano il rispettivo overload per la compatibilità di inoltro.Note that Read and Write overloads that take in baseValue, call their respective overload for forwards compatibility.

public class OrderKeySerializer : IStateSerializer<OrderKey>
{
  OrderKey IStateSerializer<OrderKey>.Read(BinaryReader reader)
  {
      var value = new OrderKey();
      value.Warehouse = reader.ReadByte();
      value.District = reader.ReadInt16();
      value.Customer = reader.ReadInt32();
      value.Order = reader.ReadInt64();

      return value;
  }

  void IStateSerializer<OrderKey>.Write(OrderKey value, BinaryWriter writer)
  {
      writer.Write(value.Warehouse);
      writer.Write(value.District);
      writer.Write(value.Customer);
      writer.Write(value.Order);
  }

  // Read overload for differential de-serialization
  OrderKey IStateSerializer<OrderKey>.Read(OrderKey baseValue, BinaryReader reader)
  {
      return ((IStateSerializer<OrderKey>)this).Read(reader);
  }

  // Write overload for differential serialization
  void IStateSerializer<OrderKey>.Write(OrderKey baseValue, OrderKey newValue, BinaryWriter writer)
  {
      ((IStateSerializer<OrderKey>)this).Write(newValue, writer);
  }
}

AggiornamentoUpgradability

In un aggiornamento in sequenza di un'applicazionel'aggiornamento viene applicato a un subset di nodi, procedendo con un dominio di aggiornamento per volta.In a rolling application upgrade, the upgrade is applied to a subset of nodes, one upgrade domain at a time. Durante questo processo, alcuni domini di aggiornamento si troveranno con la versione dell'applicazione più recente e altri con quella meno recente.During this process, some upgrade domains will be on the newer version of your application, and some upgrade domains will be on the older version of your application. Nella fase di distribuzione, la versione dell'applicazione più recente deve essere in grado di leggere la versione dei dati meno recente e viceversa.During the rollout, the new version of your application must be able to read the old version of your data, and the old version of your application must be able to read the new version of your data. Se il formato dei dati non è compatibile con le versioni successive e precedenti, è possibile che l'aggiornamento abbia esito negativo o, peggio ancora, che i dati vengano persi o danneggiati.If the data format is not forward and backward compatible, the upgrade may fail, or worse, data may be lost or corrupted.

Se si usano serializzatori predefiniti, non esistono problemi di compatibilità.If you are using built-in serializer, you do not have to worry about compatibility. Tuttavia, se si usa un serializzatore personalizzato o DataContractSerializer, i dati devono essere compatibili all'infinito con le versioni precedenti e successive.However, if you are using a custom serializer or the DataContractSerializer, the data have to be infinitely backwards and forwards compatible. In altri termini, ogni versione del serializzatore deve essere in grado di serializzare e deserializzare qualsiasi versione del tipo.In other words, each version of serializer needs to be able to serialize and de-serialize any version of the type.

Gli utenti del contratto di dati devono seguire regole ben definite di controllo delle versioni per l'aggiunta, la rimozione e la modifica di campi.Data Contract users should follow the well-defined versioning rules for adding, removing, and changing fields. Il contratto di dati supporta inoltre l'eredità delle classi, la gestione dei campi sconosciuti e l'uso di hook nel processo di serializzazione e deserializzazione.Data Contract also has support for dealing with unknown fields, hooking into the serialization and deserialization process, and dealing with class inheritance. Per altre informazioni, vedere Utilizzo di contratti dati.For more information, see Using Data Contract.

Gli utenti di serializzatori personalizzati devono seguire le linee guida del serializzatore in uso per verificarne la compatibilità con le versioni precedenti e successive.Custom serializer users should adhere to the guidelines of the serializer they are using to make sure it is backwards and forwards compatible. Un modo comune per supportare tutte le versioni consiste nell'aggiungere le informazioni sulle dimensioni all'inizio e nell'aggiungere soltanto proprietà facoltative.Common way of supporting all versions is adding size information at the beginning and only adding optional properties. In questo modo ogni versione può leggere tutto quanto è in grado di leggere, saltando la rimanente parte del flusso.This way each version can read as much it can and jump over the remaining part of the stream.

Passaggi successiviNext steps