Dela via


Serialisering av reliable collection-objekt i Azure Service Fabric

Reliable Collections replikerar och bevarar sina objekt för att se till att de är varaktiga vid datorfel och strömavbrott. Både för att replikera och bevara objekt måste Reliable Collections serialisera dem.

Reliable Collections hämtar lämplig serialiserare för en viss typ från Reliable State Manager. Reliable State Manager innehåller inbyggda serialiserare och tillåter att anpassade serialiserare registreras för en viss typ.

Inbyggda serialiserare

Reliable State Manager innehåller inbyggd serialiserare för vissa vanliga typer, så att de kan serialiseras effektivt som standard. För andra typer återgår Reliable State Manager till att använda DataContractSerializer. Inbyggda serialiserare är mer effektiva eftersom de vet att deras typer inte kan ändras och de inte behöver inkludera information om typen som dess typnamn.

Reliable State Manager har inbyggd serialiserare för följande typer:

  • GUID
  • boolesk
  • byte
  • sbyte
  • byte[]
  • char
  • sträng
  • decimal
  • double
  • flyt
  • int
  • uint
  • long
  • ulong
  • short
  • ushort

Anpassad serialisering

Anpassade serialiserare används ofta för att öka prestanda eller kryptera data över kabeln och på disken. Bland annat är anpassade serialiserare ofta effektivare än generisk serialiserare eftersom de inte behöver serialisera information om typen.

IReliableStateManager.TryAddStateSerializer< T> används för att registrera en anpassad serialiserare för den angivna typen T. Den här registreringen bör ske i konstruktionen av StatefulServiceBase för att säkerställa att alla Reliable Collections har åtkomst till relevant serialiserare innan återställningen startar för att läsa deras bevarade data.

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

Anteckning

Anpassade serialiserare ges företräde framför inbyggda serialiserare. När till exempel en anpassad serialiserare för int registreras används den för att serialisera heltal i stället för den inbyggda serialiseraren för int.

Implementera en anpassad serialiserare

En anpassad serialiserare måste implementera IStateSerializer<T-gränssnittet> .

Anteckning

IStateSerializer<T> innehåller en överlagring för skrivning och läsning som tar in ytterligare ett T-värde som kallas basvärde. Det här API:et är för differentiell serialisering. Den differentiella serialiseringsfunktionen exponeras för närvarande inte. Därför anropas inte dessa två överlagringar förrän differentiell serialisering har exponerats och aktiverats.

Följande är en exempelanpassad typ med namnet OrderKey som innehåller fyra egenskaper

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
}

Följande är ett exempel på implementering av IStateSerializer<OrderKey>. Observera att överlagringar av läsning och skrivning som tar i baseValue anropar deras respektive överlagring för vidarebefordran-kompatibilitet.

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

Uppgradering

I en löpande programuppgradering tillämpas uppgraderingen på en delmängd noder, en uppgraderingsdomän i taget. Under den här processen kommer vissa uppgraderingsdomäner att finnas på den nyare versionen av ditt program, och vissa uppgraderingsdomäner kommer att finnas på den äldre versionen av ditt program. Under distributionen måste den nya versionen av programmet kunna läsa den gamla versionen av dina data, och den gamla versionen av programmet måste kunna läsa den nya versionen av dina data. Om dataformatet inte är framåt- och bakåtkompatibelt kan uppgraderingen misslyckas, eller ännu värre, data kan gå förlorade eller skadas.

Om du använder inbyggd serialiserare behöver du inte bekymra dig om kompatibilitet. Men om du använder en anpassad serialiserare eller DataContractSerializer måste data vara oändligt bakåt- och framåtkompatibla. Med andra ord måste varje version av serialiseraren kunna serialisera och av-serialisera vilken version som helst av typen.

Datakontraktsanvändare bör följa de väldefinierade versionsreglerna för att lägga till, ta bort och ändra fält. Data contract har också stöd för att hantera okända fält, koppla in sig i serialiserings- och deserialiseringsprocessen och hantera klassarv. Mer information finns i Använda datakontrakt.

Anpassade serialiseraranvändare bör följa riktlinjerna för serialiseraren som de använder för att se till att den är bakåt- och framåtkompatibel. Ett vanligt sätt att stödja alla versioner är att lägga till storleksinformation i början och bara lägga till valfria egenskaper. På så sätt kan varje version läsa så mycket den kan och hoppa över den återstående delen av strömmen.

Nästa steg