Back-up en herstel van Reliable Services en Reliable Actors

Azure Service Fabric is een platform met hoge beschikbaarheid dat de status repliceert op meerdere knooppunten om deze hoge beschikbaarheid te behouden. Dus zelfs als één knooppunt in het cluster uitvalt, blijven de services beschikbaar. Hoewel deze ingebouwde redundantie van het platform voor sommigen voldoende kan zijn, is het in bepaalde gevallen wenselijk dat de service back-ups van gegevens maakt (naar een externe opslag).

Notitie

Het is essentieel om een back-up van uw gegevens te maken en te herstellen (en te testen of deze werken zoals verwacht), zodat u kunt herstellen van scenario's voor gegevensverlies.

Notitie

Microsoft raadt aan periodieke back-up en herstel te gebruiken voor het configureren van gegevensback-up van Reliable Stateful-services en Reliable Actors.

Een service kan bijvoorbeeld een back-up van gegevens maken om te beschermen tegen de volgende scenario's:

  • In het geval van permanent verlies van een volledig Service Fabric-cluster.
  • Permanent verlies van een meerderheid van de replica's van een servicepartitie
  • Beheerfouten waarbij de status per ongeluk wordt verwijderd of beschadigd. Dit kan bijvoorbeeld gebeuren als een beheerder met voldoende bevoegdheden de service per ongeluk verwijdert.
  • Fouten in de service die gegevensbeschadiging veroorzaken. Dit kan bijvoorbeeld gebeuren wanneer een servicecode-upgrade begint met het schrijven van onjuiste gegevens naar een betrouwbare verzameling. In een dergelijk geval moeten zowel de code als de gegevens mogelijk worden teruggezet naar een eerdere status.
  • Offline gegevensverwerking. Het kan handig zijn om offline verwerking van gegevens voor business intelligence te hebben die afzonderlijk plaatsvindt van de service die de gegevens genereert.

Met de functie Back-up/herstel kunnen services die zijn gebouwd op de Reliable Services-API back-ups maken en herstellen. De back-up-API's die door het platform worden geleverd, staan back-ups van de status van een servicepartitie toe, zonder lees- of schrijfbewerkingen te blokkeren. Met de herstel-API's kan de status van een servicepartitie worden hersteld vanuit een gekozen back-up.

Typen back-ups

Er zijn twee back-upopties: Volledig en Incrementeel. Een volledige back-up is een back-up die alle gegevens bevat die nodig zijn om de status van de replica opnieuw te maken: controlepunten en alle logboekrecords. Omdat het de controlepunten en het logboek bevat, kan een volledige back-up vanzelf worden hersteld.

Het probleem met volledige back-ups doet zich voor wanneer de controlepunten groot zijn. Een replica met een status van 16 GB heeft bijvoorbeeld controlepunten die ongeveer 16 GB groot zijn. Als we een herstelpuntdoelstelling van vijf minuten hebben, moet er elke vijf minuten een back-up van de replica worden gemaakt. Telkens wanneer er een back-up wordt gemaakt, moet er 16 GB aan controlepunten worden gekopieerd naast 50 MB (configureerbaar met ) CheckpointThresholdInMBaan logboeken.

Voorbeeld van volledige back-up.

De oplossing voor dit probleem is incrementele back-ups, waarbij back-up alleen de gewijzigde logboekrecords bevat sinds de laatste back-up.

Voorbeeld van incrementele back-up.

Omdat incrementele back-ups alleen wijzigingen zijn sinds de laatste back-up (bevat geen controlepunten), zijn ze meestal sneller, maar kunnen ze niet zelfstandig worden hersteld. Als u een incrementele back-up wilt herstellen, is de volledige back-upketen vereist. Een back-upketen is een keten van back-ups die begint met een volledige back-up en gevolgd door een aantal aaneengesloten incrementele back-ups.

Back-up maken van Reliable Services

De auteur van de service heeft volledige controle over wanneer back-ups moeten worden gemaakt en waar back-ups worden opgeslagen.

Als u een back-up wilt starten, moet de service de functie BackupAsyncovergenomen lid aanroepen.
Back-ups kunnen alleen worden gemaakt vanuit primaire replica's en hiervoor moet de schrijfstatus worden verleend.

Zoals hieronder wordt weergegeven, BackupAsync wordt een BackupDescription -object gebruikt, waarbij u een volledige of incrementele back-up kunt opgeven, evenals een callback-functie, Func<< BackupInfo, CancellationToken, Task<bool>>> die wordt aangeroepen wanneer de back-upmap lokaal is gemaakt en gereed is om te worden verplaatst naar een externe opslag.


BackupDescription myBackupDescription = new BackupDescription(BackupOption.Incremental,this.BackupCallbackAsync);

await this.BackupAsync(myBackupDescription);

De aanvraag voor het maken van een incrementele back-up kan mislukken met FabricMissingFullBackupException. Deze uitzondering geeft aan dat een van de volgende dingen gebeurt:

  • de replica heeft nooit een volledige back-up gemaakt omdat deze primair is geworden,
  • een deel van de logboekrecords sinds de laatste back-up is afgekapt of
  • replica heeft de MaxAccumulatedBackupLogSizeInMB limiet overschreden.

Gebruikers kunnen de kans vergroten dat ze incrementele back-ups kunnen maken door of TruncationThresholdFactorte MinLogSizeInMB configureren. Als u deze waarden verhoogt, neemt het schijfgebruik per replica toe. Zie Reliable Services Configuration (Configuratie van Reliable Services) voor meer informatie

BackupInfo biedt informatie over de back-up, waaronder de locatie van de map waarin de runtime de back-up heeft opgeslagen (BackupInfo.Directory). De callback-functie kan de BackupInfo.Directory verplaatsen naar een externe winkel of een andere locatie. Deze functie retourneert ook een bool die aangeeft of de back-upmap naar de doellocatie is verplaatst.

De volgende code laat zien hoe de BackupCallbackAsync methode kan worden gebruikt om de back-up te uploaden naar Azure Storage:

private async Task<bool> BackupCallbackAsync(BackupInfo backupInfo, CancellationToken cancellationToken)
{
    var backupId = Guid.NewGuid();

    await externalBackupStore.UploadBackupFolderAsync(backupInfo.Directory, backupId, cancellationToken);

    return true;
}

In het voorgaande voorbeeld ExternalBackupStore is de voorbeeldklasse die wordt gebruikt voor de interface met Azure Blob Storage. UploadBackupFolderAsync Dit is de methode waarmee de map wordt gecomprimeerd en in het Azure Blob-archief wordt geplaatst.

Opmerking:

  • Er kan op elk moment slechts één back-upbewerking per replica worden uitgevoerd. Er worden meer dan één BackupAsync aanroep tegelijk uitgevoerd FabricBackupInProgressException om back-ups aan boord te beperken tot één.
  • Als een failover van een replica wordt uitgevoerd terwijl een back-up wordt uitgevoerd, is de back-up mogelijk niet voltooid. Zodra de failover is voltooid, is het dus de verantwoordelijkheid van de service om de back-up opnieuw te starten door indien nodig aan te roepen BackupAsync .

Reliable Services herstellen

In het algemeen vallen de gevallen waarin u mogelijk een herstelbewerking moet uitvoeren, in een van deze categorieën:

  • De servicepartitie heeft gegevens verloren. De schijf voor twee van de drie replica's voor een partitie (inclusief de primaire replica) wordt bijvoorbeeld beschadigd of gewist. De nieuwe primaire moet mogelijk gegevens herstellen vanuit een back-up.
  • De hele service is verloren gegaan. Een beheerder verwijdert bijvoorbeeld de hele service en dus moeten de service en de gegevens worden hersteld.
  • De service heeft beschadigde toepassingsgegevens gerepliceerd (bijvoorbeeld vanwege een toepassingsfout). In dit geval moet de service worden bijgewerkt of teruggezet om de oorzaak van de beschadiging te verwijderen en moeten niet-beschadigde gegevens worden hersteld.

Hoewel er veel benaderingen mogelijk zijn, bieden we enkele voorbeelden van het gebruik RestoreAsync om te herstellen van de bovenstaande scenario's.

Gegevensverlies partitioneren in Reliable Services

In dit geval detecteert de runtime automatisch het gegevensverlies en roept de API aan OnDataLossAsync .

De auteur van de service moet het volgende uitvoeren om te herstellen:

  • Overschrijf de virtuele basisklassemethode OnDataLossAsync.
  • Zoek de meest recente back-up op de externe locatie die de back-ups van de service bevat.
  • Download de meest recente back-up (en decomprimeert de back-up in de back-upmap als deze is gecomprimeerd).
  • De OnDataLossAsync methode biedt een RestoreContext. Roep de RestoreAsync API aan op de opgegeven RestoreContext.
  • Retourneer waar als de herstelbewerking is geslaagd.

Hier volgt een voorbeeld van de implementatie van de OnDataLossAsync methode:

protected override async Task<bool> OnDataLossAsync(RestoreContext restoreCtx, CancellationToken cancellationToken)
{
    var backupFolder = await this.externalBackupStore.DownloadLastBackupAsync(cancellationToken);

    var restoreDescription = new RestoreDescription(backupFolder);

    await restoreCtx.RestoreAsync(restoreDescription);

    return true;
}

RestoreDescription doorgegeven aan de aanroep bevat een lid met de RestoreContext.RestoreAsync naam BackupFolderPath. Wanneer u één volledige back-up herstelt, moet deze BackupFolderPath worden ingesteld op het lokale pad van de map die uw volledige back-up bevat. Bij het herstellen van een volledige back-up en een aantal incrementele back-ups BackupFolderPath moet worden ingesteld op het lokale pad van de map die niet alleen de volledige back-up bevat, maar ook alle incrementele back-ups. RestoreAsync aanroep kan worden gegooid FabricMissingFullBackupException als de BackupFolderPath opgegeven geen volledige back-up bevat. Het kan ook genereren ArgumentException als BackupFolderPath er een verbroken keten van incrementele back-ups is. Als deze bijvoorbeeld de volledige back-up bevat, de eerste incrementele en de derde incrementele back-up, maar niet de tweede incrementele back-up.

Notitie

RestorePolicy is standaard ingesteld op Veilig. Dit betekent dat de RestoreAsync API mislukt met ArgumentException als wordt gedetecteerd dat de back-upmap een status bevat die ouder is dan of gelijk is aan de status in deze replica. RestorePolicy.Force kan worden gebruikt om deze veiligheidscontrole over te slaan. Dit wordt opgegeven als onderdeel van RestoreDescription.

Verwijderde of verloren service

Als een service wordt verwijderd, moet u de service eerst opnieuw maken voordat de gegevens kunnen worden hersteld. Het is belangrijk om de service te maken met dezelfde configuratie, bijvoorbeeld partitioneringsschema, zodat de gegevens naadloos kunnen worden hersteld. Zodra de service is ingeschakeld, moet de API voor het herstellen van gegevens (OnDataLossAsync hierboven) worden aangeroepen op elke partitie van deze service. Een manier om dit te bereiken, is met behulp van FabricClient.TestManagementClient.StartPartitionDataLossAsync op elke partitie.

Vanaf dit punt is de implementatie hetzelfde als het bovenstaande scenario. Elke partitie moet de meest recente relevante back-up herstellen vanuit het externe archief. Een waarschuwing is dat de partitie-id nu mogelijk is gewijzigd, omdat de runtime dynamisch partitie-id's maakt. De service moet dus de juiste partitiegegevens en servicenaam opslaan om de juiste meest recente back-up te identificeren voor elke partitie.

Notitie

Het wordt niet aanbevolen om op elke partitie te gebruiken FabricClient.ServiceManager.InvokeDataLossAsync om de hele service te herstellen, omdat dit de status van uw cluster kan beschadigen.

Replicatie van beschadigde toepassingsgegevens

Als de zojuist geïmplementeerde toepassingsupgrade een fout heeft, kan dit leiden tot beschadiging van de gegevens. Een toepassingsupgrade kan bijvoorbeeld beginnen met het bijwerken van elke telefoonnummerrecord in een betrouwbare woordenlijst met een ongeldig netnummer. In dit geval worden de ongeldige telefoonnummers gerepliceerd omdat Service Fabric zich niet bewust is van de aard van de gegevens die worden opgeslagen.

Het eerste wat u moet doen nadat u een dergelijke flagrante fout hebt gedetecteerd die gegevensbeschadiging veroorzaakt, is de service op toepassingsniveau blokkeren en, indien mogelijk, upgraden naar de versie van de toepassingscode die de fout niet bevat. Zelfs nadat de servicecode is opgelost, kunnen de gegevens echter nog steeds beschadigd zijn en moeten de gegevens mogelijk worden hersteld. In dergelijke gevallen is het mogelijk niet voldoende om de meest recente back-up te herstellen, omdat de meest recente back-ups ook beschadigd kunnen zijn. U moet dus de laatste back-up vinden die is gemaakt voordat de gegevens beschadigd raakten.

Als u niet zeker weet welke back-ups beschadigd zijn, kunt u een nieuw Service Fabric-cluster implementeren en de back-ups van de betrokken partities herstellen, net zoals in het bovenstaande scenario 'Verwijderde of verloren service'. Begin voor elke partitie met het herstellen van de back-ups van de meest recente naar de minst. Zodra u een back-up hebt gevonden die niet beschadigd is, verplaatst/verwijdert u alle back-ups van deze partitie die recenter waren (dan die back-up). Herhaal dit proces voor elke partitie. Wanneer OnDataLossAsync nu wordt aangeroepen op de partitie in het productiecluster, is de laatste back-up die is gevonden in de externe opslag de back-up die is gekozen door het bovenstaande proces.

Nu kunnen de stappen in de sectie 'Verwijderde of verloren service' worden gebruikt om de status van de service te herstellen naar de status voordat de buggy-code de status heeft beschadigd.

Opmerking:

  • Wanneer u herstelt, bestaat de kans dat de back-up die wordt hersteld, ouder is dan de status van de partitie voordat de gegevens verloren zijn gegaan. Daarom moet u alleen herstellen als laatste redmiddel om zoveel mogelijk gegevens te herstellen.
  • De tekenreeks die het pad van de back-upmap en de paden van bestanden in de back-upmap vertegenwoordigt, kan langer zijn dan 255 tekens, afhankelijk van het Pad fabricDataRoot en de lengte van de naam van het toepassingstype. Dit kan ertoe leiden dat sommige .NET-methoden, zoals Directory.Move, de PathTooLongException uitzondering genereren. Een tijdelijke oplossing is om kernel32 API's rechtstreeks aan te roepen, zoals CopyFile.

Een back-up maken van Reliable Actors en deze herstellen

Reliable Actors Framework is gebaseerd op Reliable Services. De ActorService, die als host fungeert voor de actor(s) is een stateful betrouwbare service. Daarom is alle back-up- en herstelfunctionaliteit die beschikbaar is in Reliable Services ook beschikbaar voor Reliable Actors (met uitzondering van gedrag dat specifiek is voor de statusprovider). Omdat back-ups per partitie worden gemaakt, wordt er een back-up gemaakt van statussen voor alle actoren in die partitie (en herstel is vergelijkbaar en vindt per partitie plaats). Als u een back-up/herstel wilt uitvoeren, moet de eigenaar van de service een aangepaste actorserviceklasse maken die is afgeleid van de klasse ActorService en vervolgens een back-up/herstel uitvoeren die vergelijkbaar is met Reliable Services zoals hierboven beschreven in de vorige secties.

class MyCustomActorService : ActorService
{
    public MyCustomActorService(StatefulServiceContext context, ActorTypeInformation actorTypeInfo)
          : base(context, actorTypeInfo)
    {
    }
    
    //
    // Method overrides and other code.
    //
}

Wanneer u een aangepaste actorserviceklasse maakt, moet u deze ook registreren bij het registreren van de actor.

ActorRuntime.RegisterActorAsync<MyActor>(
    (context, typeInfo) => new MyCustomActorService(context, typeInfo)).GetAwaiter().GetResult();

De standaardstatusprovider voor Reliable Actors is KvsActorStateProvider. Incrementele back-up is niet standaard ingeschakeld voor KvsActorStateProvider. U kunt incrementele back-up inschakelen door deze te maken KvsActorStateProvider met de juiste instelling in de constructor en deze vervolgens door te geven aan de ActorService-constructor, zoals wordt weergegeven in het volgende codefragment:

class MyCustomActorService : ActorService
{
    public MyCustomActorService(StatefulServiceContext context, ActorTypeInformation actorTypeInfo)
          : base(context, actorTypeInfo, null, null, new KvsActorStateProvider(true)) // Enable incremental backup
    {
    }
    
    //
    // Method overrides and other code.
    //
}

Nadat incrementele back-up is ingeschakeld, kan het maken van een incrementele back-up mislukken met FabricMissingFullBackupException om een van de volgende redenen. U moet een volledige back-up maken voordat u incrementele back-ups maakt:

  • De replica heeft nooit een volledige back-up gemaakt sinds deze primair is geworden.
  • Sommige logboekrecords zijn afgekapt sinds de laatste back-up is gemaakt.

Wanneer incrementele back-up is ingeschakeld, KvsActorStateProvider wordt er geen circulaire buffer gebruikt om de logboekrecords te beheren en wordt deze periodiek afgekapt. Als de gebruiker gedurende een periode van 45 minuten geen back-up maakt, worden de logboekrecords automatisch afgekapt. Dit interval kan worden geconfigureerd door op te logTruncationIntervalInMinutes geven in KvsActorStateProvider de constructor (vergelijkbaar met bij het inschakelen van incrementele back-up). De logboekrecords kunnen ook worden afgekapt als de primaire replica een andere replica moet bouwen door alle bijbehorende gegevens te verzenden.

Wanneer u herstel uitvoert vanuit een back-upketen, vergelijkbaar met Reliable Services, moet de BackupFolderPath submappen bevatten met één submap met volledige back-up en andere submappen met incrementele back-up(s). De herstel-API genereert FabricException met het juiste foutbericht als de validatie van de back-upketen mislukt.

Notitie

KvsActorStateProvider negeert momenteel de optie RestorePolicy.Safe. Ondersteuning voor deze functie is gepland in een toekomstige release.

Back-up en herstel testen

Het is belangrijk om ervoor te zorgen dat er een back-up wordt gemaakt van kritieke gegevens en dat deze kunnen worden hersteld. Dit kan worden gedaan door de Start-ServiceFabricPartitionDataLoss cmdlet in PowerShell aan te roepen die gegevensverlies in een bepaalde partitie kan veroorzaken om te testen of de back-up- en herstelfunctionaliteit voor uw service werkt zoals verwacht. Het is ook mogelijk om gegevensverlies en herstel programmatisch aan te roepen vanuit die gebeurtenis.

Notitie

U vindt een voorbeeld van de implementatie van back-up- en herstelfunctionaliteit in de Web Reference App op GitHub. Raadpleeg de Inventory.Service service voor meer informatie.

Onder de motorkap: meer informatie over back-up en herstel

Hier vindt u meer informatie over back-up en herstel.

Backup

Reliable State Manager biedt de mogelijkheid om consistente back-ups te maken zonder lees- of schrijfbewerkingen te blokkeren. Hiervoor wordt gebruikgemaakt van een controlepunt- en logboekpersistentiemechanisme. De Reliable State Manager gebruikt op bepaalde punten fuzzy (lichtgewicht) controlepunten om de druk van het transactionele logboek te verlichten en hersteltijden te verbeteren. Wanneer BackupAsync wordt aangeroepen, geeft Reliable State Manager alle Reliable-objecten de opdracht om de meest recente controlepuntbestanden te kopiëren naar een lokale back-upmap. Vervolgens kopieert Reliable State Manager alle logboekrecords, beginnend van de 'beginaanwijzer' naar de meest recente logboekrecord in de back-upmap. Aangezien alle logboekrecords tot de meest recente logboekrecord zijn opgenomen in de back-up en Reliable State Manager write-ahead-logboekregistratie behoudt, garandeert Reliable State Manager dat alle transacties die zijn doorgevoerd (CommitAsync heeft geretourneerd) worden opgenomen in de back-up.

Elke transactie die wordt doorgevoerd nadat BackupAsync is aangeroepen, kan al dan niet in de back-up staan. Zodra de lokale back-upmap is gevuld door het platform (dat wil gezegd, lokale back-up wordt voltooid door de runtime), wordt de back-upaanroep van de service aangeroepen. Deze callback is verantwoordelijk voor het verplaatsen van de back-upmap naar een externe locatie, zoals Azure Storage.

Herstellen

Reliable State Manager biedt de mogelijkheid om te herstellen vanuit een back-up met behulp van de RestoreAsync API.
De RestoreAsync methode aan RestoreContext kan alleen worden aangeroepen binnen de OnDataLossAsync methode. De bool geretourneerd door OnDataLossAsync geeft aan of de service de status van een externe bron heeft hersteld. Als de OnDataLossAsync true retourneert, worden alle andere replica's van deze primaire replica opnieuw opgebouwd. Service Fabric zorgt ervoor dat replica's die de aanroep ontvangen de eerste overgang naar de primaire rol, OnDataLossAsync maar geen lees- of schrijfstatus krijgen. Dit betekent dat voor StatefulService-implementeerprogramma's RunAsync niet wordt aangeroepen totdat OnDataLossAsync de uitvoering is voltooid. OnDataLossAsync Vervolgens wordt aangeroepen op de nieuwe primaire. Totdat een service deze API heeft voltooid (door waar of onwaar te retourneren) en de relevante herconfiguratie heeft voltooid, wordt de API één voor één aangeroepen.

RestoreAsync verwijdert eerst alle bestaande status in de primaire replica waarop deze is aangeroepen. Vervolgens maakt Reliable State Manager alle Reliable-objecten die aanwezig zijn in de back-upmap. Vervolgens krijgen de Reliable-objecten de instructie om te herstellen vanaf de controlepunten in de back-upmap. Ten slotte herstelt Reliable State Manager zijn eigen status uit de logboekrecords in de back-upmap en voert het herstel uit. Als onderdeel van het herstelproces worden bewerkingen vanaf het 'beginpunt' die logboekrecords in de back-upmap hebben vastgelegd, opnieuw afgespeeld naar de Reliable-objecten. Deze stap zorgt ervoor dat de herstelde status consistent is.

Volgende stappen