Delen via


Serialisatie van betrouwbare verzamelingsobjecten in Azure Service Fabric

Betrouwbare verzamelingen repliceren en behouden hun items om ervoor te zorgen dat ze duurzaam zijn bij machinestoringen en stroomstoringen. Zowel om items te repliceren als te behouden, moeten ze worden geserialiseerd door Reliable Collections.

Reliable Collections's krijgen de juiste serializer voor een bepaald type van Reliable State Manager. Reliable State Manager bevat ingebouwde serializers en staat toe dat aangepaste serializers voor een bepaald type worden geregistreerd.

Ingebouwde serializers

Reliable State Manager bevat ingebouwde serialisatiefunctie voor enkele veelvoorkomende typen, zodat ze standaard efficiënt kunnen worden geserialiseerd. Voor andere typen valt Reliable State Manager terug om de DataContractSerializer te gebruiken. Ingebouwde serialisatieprogramma's zijn efficiënter omdat ze weten dat hun typen niet kunnen worden gewijzigd en ze hoeven geen informatie over het type op te nemen, zoals de naam van het type.

Reliable State Manager heeft ingebouwde serializer voor de volgende typen:

  • Guid
  • bool
  • byte
  • sbyte
  • byte[]
  • char
  • tekenreeks
  • decimal
  • dubbel
  • zwevend
  • int
  • uint
  • long
  • ulong
  • kort
  • ushort

Aangepaste serialisatie

Aangepaste serializers worden vaak gebruikt om de prestaties te verbeteren of om de gegevens via de kabel en op schijf te versleutelen. Onder andere zijn aangepaste serializers vaak efficiënter dan algemene serialisatiefunctie, omdat ze geen informatie over het type hoeven te serialiseren.

IReliableStateManager.TryAddStateSerializer<T> wordt gebruikt om een aangepaste serializer te registreren voor het opgegeven type T. Deze registratie moet plaatsvinden in de bouw van statefulServiceBase om ervoor te zorgen dat voordat het herstel wordt gestart, alle Reliable Collections toegang hebben tot de relevante serializer om hun persistente gegevens te lezen.

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

Notitie

Aangepaste serializers krijgen voorrang op ingebouwde serializers. Wanneer bijvoorbeeld een aangepaste serializer voor int is geregistreerd, wordt deze gebruikt om gehele getallen te serialiseren in plaats van de ingebouwde serializer voor int.

Een aangepaste serialisatiefunctie implementeren

Een aangepaste serializer moet de IStateSerializer<T-interface> implementeren.

Notitie

IStateSerializer<T> bevat een overbelasting voor schrijven en lezen die een extra T met de naam basiswaarde inneemt. Deze API is bedoeld voor differentiële serialisatie. De functie voor differentiële serialisatie wordt momenteel niet weergegeven. Daarom worden deze twee overbelastingen niet aangeroepen totdat differentiële serialisatie wordt weergegeven en ingeschakeld.

Hieronder volgt een voorbeeld van een aangepast type met de naam OrderKey dat vier eigenschappen bevat

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
}

Hieronder volgt een voorbeeldimplementatie van IStateSerializer<OrderKey>. Houd er rekening mee dat lees- en schrijfoverbelastingen die in baseValue worden opgenomen, hun respectieve overbelasting aanroepen voor compatibiliteit met doorstuurbewerkingen.

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);
  }
}

Upgrademogelijkheden

In een rolling toepassingsupgrade wordt de upgrade toegepast op een subset van knooppunten, één upgradedomein tegelijk. Tijdens dit proces bevinden sommige upgradedomeinen zich in de nieuwere versie van uw toepassing, en sommige upgradedomeinen bevinden zich in de oudere versie van uw toepassing. Tijdens de implementatie moet de nieuwe versie van uw toepassing de oude versie van uw gegevens kunnen lezen en moet de oude versie van uw toepassing de nieuwe versie van uw gegevens kunnen lezen. Als de gegevensindeling niet compatibel is met vooruit en achteruit, kan de upgrade mislukken, of erger, gegevens verloren gaan of beschadigd zijn.

Als u ingebouwde serializer gebruikt, hoeft u zich geen zorgen te maken over compatibiliteit. Als u echter een aangepaste serializer of de DataContractSerializer gebruikt, moeten de gegevens oneindig achterwaarts en vooruit compatibel zijn. Met andere woorden, elke versie van serializer moet elke versie van het type kunnen serialiseren en de serialiseren.

Gebruikers van het gegevenscontract moeten de goed gedefinieerde versiebeheerregels volgen voor het toevoegen, verwijderen en wijzigen van velden. Data Contract biedt ook ondersteuning voor het verwerken van onbekende velden, het koppelen aan het serialisatie- en deserialisatieproces en het omgaan met de overname van klassen. Zie Gegevenscontract gebruiken voor meer informatie.

Aangepaste serializergebruikers moeten voldoen aan de richtlijnen van de serialisatiefunctie die ze gebruiken om ervoor te zorgen dat deze compatibel is met achteruit en vooruit. Algemene manier om alle versies te ondersteunen, is het toevoegen van groottegegevens aan het begin en alleen optionele eigenschappen toevoegen. Op deze manier kan elke versie zoveel mogelijk lezen en over het resterende deel van de stream springen.

Volgende stappen