Entwerfen von hochverfügbaren Anwendungen mit georedundantem Speicher mit LesezugriffDesigning highly available applications using read-access geo-redundant storage

Ein Feature von cloudbasierten Infrastrukturen wie Azure Storage ist, dass sie eine hochverfügbare Plattform zum Hosten von Anwendungen bereitstellen.A common feature of cloud-based infrastructures like Azure Storage is that they provide a highly available platform for hosting applications. Entwickler von cloudbasierten Anwendungen müssen genau überlegen, wie sie diese Plattform zum Bereitstellen hochverfügbarer Anwendungen für ihre Benutzer verwenden.Developers of cloud-based applications must consider carefully how to leverage this platform to deliver highly available applications to their users. Dieser Artikel konzentriert sich darauf, wie Entwickler eine der georedundantenn Replikationsoptionen von Azure verwenden können, um die Hochverfügbarkeit ihrer Azure Storage-Anwendungen sicherzustellen.This article focuses on how developers can use one of Azure's geo-redundant replication options to ensure that their Azure Storage applications are highly available.

Speicherkonten, die für die georedundante Replikation konfiguriert sind, werden synchron in die primäre Region und dann asynchron in eine sekundäre Region repliziert, die Hunderte von Kilometern entfernt ist.Storage accounts configured for geo-redundant replication are synchronously replicated in the primary region, and then asynchronously replicated to a secondary region that is hundreds of miles away. Azure Storage bietet zwei Arten der georedundanten Replikation:Azure Storage offers two types of geo-redundant replication:

  • Geozonenredundanter Speicher (GZRS) (Vorschau) ermöglicht die Replikation für Szenarien, die sowohl Hochverfügbarkeit als auch maximale Dauerhaftigkeit erfordern.Geo-zone-redundant storage (GZRS) (preview) provides replication for scenarios requiring both high availability and maximum durability. Die Daten werden synchron über drei Azure-Verfügbarkeitszonen in die primären Region mithilfe von zoneredundantem Speicher (ZRS) repliziert und anschließend asynchron in die sekundäre Region repliziert.Data is replicated synchronously across three Azure availability zones in the primary region using zone-redundant storage (ZRS), then replicated asynchronously to the secondary region. Aktivieren Sie für den Lesezugriff auf die Daten in der sekundären Region den geozonenredundanten Speicher mit Lesezugriff (RA-GZRS).For read access to data in the secondary region, enable read-access geo-zone-redundant storage (RA-GZRS).
  • Georedundanter Speicher (GRS) bietet regionsübergreifende Replikation zum Schutz vor regionalen Ausfällen.Geo-redundant storage (GRS) provides cross-regional replication to protect against regional outages. Die Daten werden in der primären Region unter Verwendung von lokal redundantem Speicher (LRS) drei Mal synchron repliziert und dann asynchron in die sekundäre Region repliziert.Data is replicated synchronously three times in the primary region using locally redundant storage (LRS), then replicated asynchronously to the secondary region. Aktivieren Sie für den Lesezugriff auf die Daten in der sekundären Region den georedundanten Speicher mit Lesezugriff (RA-GRS).For read access to data in the secondary region, enable read-access geo-redundant storage (RA-GRS).

In diesem Artikel wird gezeigt, wie Sie Ihre Anwendung so entwerfen, dass sie einen Ausfall in der primären Region verarbeiten kann.This article shows how to design your application to handle an outage in the primary region. Wenn die primäre Region nicht mehr verfügbar ist, kann sich Ihre Anwendung anpassen, um stattdessen Lesevorgänge in der sekundären Region durchzuführen.If the primary region becomes unavailable, your application can adapt to perform read operations against the secondary region instead. Stellen Sie sicher, dass Ihr Speicherkonto für RA-GRS oder RA-GZRS konfiguriert ist, bevor Sie beginnen.Make sure that your storage account is configured for RA-GRS or RA-GZRS before you get started.

Welche primären Regionen welchen sekundären Regionen zugeordnet werden, erfahren Sie unter Geschäftskontinuität und Notfallwiederherstellung: Azure-Regionspaare.For information about which primary regions are paired with which secondary regions, see Business continuity and disaster recovery (BCDR): Azure Paired Regions.

Der Artikel enthält Codeausschnitte sowie am Ende einen Link zu einem vollständigen Beispiel, das Sie herunterladen und ausführen können.There are code snippets included in this article, and a link to a complete sample at the end that you can download and run.

Überlegungen zum Anwendungsentwurf beim Lesen aus der sekundären RegionApplication design considerations when reading from the secondary

Der Zweck dieses Artikels ist, zu veranschaulichen, wie Sie eine Anwendung entwerfen, die auch im Fall eines schwerwiegenden Zwischenfalls im primären Rechenzentrum weiterhin funktioniert (wenn auch nur mit begrenzter Kapazität).The purpose of this article is to show you how to design an application that will continue to function (albeit in a limited capacity) even in the event of a major disaster at the primary data center. Sie können Ihre Anwendung so entwerfen, dass vorübergehende oder länger andauernde Probleme mittels Lesen aus der sekundären Region behandelt werden, wenn eine Störung das Lesen aus der primären Region behindert.You can design your application to handle transient or long-running issues by reading from the secondary region when there is a problem that interferes with reading from the primary region. Wenn die primäre Region wieder verfügbar ist, kann Ihre Anwendung das Lesen aus der primären Region wieder aufnehmen.When the primary region is available again, your application can return to reading from the primary region.

Berücksichtigen Sie beim Entwerfen Ihrer Anwendung für RA-GRS oder RA-GZRS folgende wichtige Punkte:Keep in mind these key points when designing your application for RA-GRS or RA-GZRS:

  • Azure Storage verwaltet eine schreibgeschützte Kopie der Daten, die Sie in Ihrer primären Region speichern, in einer sekundären Region.Azure Storage maintains a read-only copy of the data you store in your primary region in a secondary region. Wie oben bereits erwähnt, bestimmt der Speicherdienst den Speicherort der sekundären Region.As noted above, the storage service determines the location of the secondary region.

  • Die schreibgeschützte Kopie ist letztendlich konsistent mit den Daten in der primären Region.The read-only copy is eventually consistent with the data in the primary region.

  • Für Blobs, Tabellen und Warteschlangen können Sie den Wert für den Zeitpunkt der letzten Synchronisierung von der sekundären Region abfragen, der anzeigt, wann die letzte Replikation von der primären zur sekundären Region ausgeführt wurde.For blobs, tables, and queues, you can query the secondary region for a Last Sync Time value that tells you when the last replication from the primary to the secondary region occurred. (Dies wird für Azure Files nicht unterstützt, da RA-GRS-Redundanz zum aktuellen Zeitpunkt dort nicht verfügbar ist.)(This is not supported for Azure Files, which doesn't have RA-GRS redundancy at this time.)

  • Sie können die Speicherclientbibliothek zum Lesen und Schreiben von Daten in der primären oder sekundären Region verwenden.You can use the Storage Client Library to read and write data in either the primary or secondary region. Sie können Anforderungen auch automatisch an die sekundäre Region leiten, wenn bei einer Leseanforderung an die primäre Region eine Zeitüberschreitung auftritt.You can also redirect read requests automatically to the secondary region if a read request to the primary region times out.

  • Wenn die primäre Region nicht verfügbar ist, können Sie ein Kontofailover einleiten.If the primary region becomes unavailable, you can initiate an account failover. Wenn Sie ein Failover auf die sekundäre Region ausführen, werden die DNS-Einträge, die auf die primäre Region verweisen, so geändert, dass sie auf die sekundäre Region verweisen.When you fail over to the secondary region, the DNS entries pointing to the primary region are changed to point to the secondary region. Nachdem das Failover abgeschlossen ist, wird der Schreibzugriff für GRS und RA-GRS-Konten wiederhergestellt.After the failover is complete, write access is restored for GRS and RA-GRS accounts. Weitere Informationen finden Sie unter Notfallwiederherstellung und Failover des Speicherkontos (Vorschau) in Azure Storage.For more information, see Disaster recovery and storage account failover (preview) in Azure Storage.

Hinweis

Das vom Kunden verwaltete Kontofailover (Vorschau) ist in Regionen noch nicht verfügbar, die GZRS/RA-GZRS unterstützen, sodass Kunden derzeit keine Kontofailoverereignisse mit GZRS- und RA-GZRS-Konten verwalten können.Customer-managed account failover (preview) is not yet available in regions supporting GZRS/RA-GZRS, so customers cannot currently manage account failover events with GZRS and RA-GZRS accounts. Während der Vorschauphase verwaltet Microsoft alle Failoverereignisse, die sich auf GZRS-/RA-GZRS-Konten auswirken.During the preview, Microsoft will manage any failover events affecting GZRS/RA-GZRS accounts.

Verwenden von letztendlich konsistenten DatenUsing eventually consistent data

Die vorgeschlagene Lösung setzt voraus, dass es akzeptabel ist, möglicherweise veraltete Daten an die aufrufende Anwendung zurückzugeben.The proposed solution assumes that it is acceptable to return potentially stale data to the calling application. Da die Daten in der sekundären Region letztendlich konsistent sind, ist es möglich, dass erst dann auf die primäre Region zugegriffen werden kann, wenn die Replikation eines Updates in die sekundäre Region fertig gestellt ist.Because data in the secondary region is eventually consistent, it is possible the primary region may become inaccessible before an update to the secondary region has finished replicating.

Nehmen Sie beispielsweise an, dass Ihr Kunde erfolgreich ein Update sendet, aber die primäre Region ausfällt, bevor das Update an die sekundäre Region weitergegeben wird.For example, suppose your customer submits an update successfully, but the primary region fails before the update is propagated to the secondary region. Wenn der Kunde dann das Zurücklesen der Daten anfordert, empfängt er in diesem Fall statt der aktualisierten Daten die veralteten Daten aus der sekundären Region.When the customer asks to read the data back, they receive the stale data from the secondary region instead of the updated data. Beim Entwurf Ihrer Anwendung müssen Sie entscheiden, ob dies akzeptabel ist, und wenn ja, wie Sie den Kunden darüber informieren möchten.When designing your application, you must decide whether this is acceptable, and if so, how you will message the customer.

Weiter unten in diesem Artikel wird dargestellt, wie Sie den Zeitpunkt der letzten Synchronisierung der sekundären Daten überprüfen, um festzustellen, ob die sekundäre Region auf dem neuesten Stand ist.Later in this article, we show how to check the Last Sync Time for the secondary data to check whether the secondary is up-to-date.

Einzelnes oder gemeinsames Verarbeiten von ServicesHandling services separately or all together

Auch wenn es unwahrscheinlich ist, kann es vorkommen, dass ein Dienst nicht mehr verfügbar ist, während die anderen Dienste weiterhin voll funktionsfähig sind.While unlikely, it is possible for one service to become unavailable while the other services are still fully functional. Sie können die Wiederholungen und den schreibgeschützten Modus für jeden Dienst (Blobs, Warteschlangen, Tabellen) einzeln verarbeiten, oder Sie können Wiederholungen generisch für alle Speicherdienste zusammen verarbeiten.You can handle the retries and read-only mode for each service separately (blobs, queues, tables), or you can handle retries generically for all the storage services together.

Wenn Sie beispielsweise Warteschlangen und Blobs in Ihrer Anwendung verwenden, können Sie sich dazu entschließen, separaten Code für die Verarbeitung von Wiederholungen nach einem Fehler für jeden Fehler hinzufügen.For example, if you use queues and blobs in your application, you may decide to put in separate code to handle retryable errors for each of these. Bei einem Wiederholungsversuch des Blob-Diensts, während der Warteschlangendienst weiterhin funktioniert, wird nur der Teil der Anwendung beeinflusst, der Blobs verarbeitet.Then if you get a retry from the blob service, but the queue service is still working, only the part of your application that handles blobs will be impacted. Wenn alle Speicherdienstwiederholungen verarbeitet werden sollen und ein Aufruf an den Blob-Dienst einen wiederholbaren Fehler zurückgibt, werden Anforderungen an den Blob-Dienst und den Warteschlangendienst beeinflusst.If you decide to handle all storage service retries generically and a call to the blob service returns a retryable error, then requests to both the blob service and the queue service will be impacted.

Dies hängt letztendlich von der Komplexität Ihrer Anwendung ab.Ultimately, this depends on the complexity of your application. Sie können sich dazu entschließen, die Fehler nicht nach Dienst zu verarbeiten, sondern stattdessen Leseanforderungen für alle Speicherdienste an die sekundäre Region umzuleiten und die Anwendung im schreibgeschützten Modus auszuführen, wenn ein Problem mit dem Speicherdienst in der primären Region auftritt.You may decide not to handle the failures by service, but instead to redirect read requests for all storage services to the secondary region and run the application in read-only mode when you detect a problem with any storage service in the primary region.

Weitere ÜberlegungenOther considerations

Dies sind die weiteren Überlegungen, die im weiteren Verlauf dieses Artikels beschrieben werden.These are the other considerations we will discuss in the rest of this article.

  • Verarbeiten von Wiederholungen von Leseanforderungen mit dem Trennschalter-MusterHandling retries of read requests using the Circuit Breaker pattern

  • Letztendlich konsistente Daten und Zeitpunkt der letzten SynchronisierungEventually-consistent data and the Last Sync Time

  • TestenTesting

Ausführen der Anwendung im schreibgeschützten ModusRunning your application in read-only mode

Um sich effektiv auf einen Ausfall in der primären Region vorzubereiten, müssen Sie in der Lage sein, sowohl Leseanforderungen als auch Aktualisierungsanforderungen mit Fehlern zu verarbeiten (Aktualisierungen sind in diesem Fall Einfügungen, Aktualisierungen und Löschungen).To effectively prepare for an outage in the primary region, you must be able to handle both failed read requests and failed update requests (with update in this case meaning inserts, updates, and deletions). Wenn in der primären Region ein Fehler auftritt, können Leseanforderungen an die sekundäre Region umgeleitet werden.If the primary region fails, read requests can be redirected to the secondary region. Aktualisierungsanforderungen können jedoch nicht in den sekundären Speicher umgeleitet werden, da dieser schreibgeschützt ist.However, update requests cannot be redirected to the secondary because the secondary is read-only. Aus diesem Grund müssen Sie Ihre Anwendung so entwerfen, dass sie im schreibgeschützten Modus ausgeführt wird.For this reason, you need to design your application to run in read-only mode.

Sie können beispielsweise ein Flag festlegen, das vor dem Übermitteln von Aktualisierungsanforderungen an Azure Storage geprüft wird.For example, you can set a flag that is checked before any update requests are submitted to Azure Storage. Wenn eine der Aktualisierungsanforderungen übermittelt wird, können Sie sie überspringen und eine entsprechende Antwort an den Kunden zurückgeben.When one of the update requests comes through, you can skip it and return an appropriate response to the customer. Sie können auch bestimmte Features insgesamt deaktivieren, bis das Problem gelöst ist, und die Benutzer darüber benachrichtigen, dass diese Funktionen vorübergehend nicht verfügbar sind.You may even want to disable certain features altogether until the problem is resolved and notify users that those features are temporarily unavailable.

Wenn Sie sich entscheiden, Fehler für jeden Dienst einzeln zu verarbeiten, müssen Sie auch die Möglichkeit zum Ausführen der Anwendung im schreibgeschützten Modus nach Dienst verarbeiten.If you decide to handle errors for each service separately, you will also need to handle the ability to run your application in read-only mode by service. Beispielsweise haben Sie möglicherweise Schreibschutzflags für jeden Dienst, die aktiviert und deaktiviert werden können.For example, you may have read-only flags for each service that can be enabled and disabled. Dann können Sie das Flag an den entsprechenden Stellen im Code verwenden.Then you can handle the flag in the appropriate places in your code.

Ein weiterer Vorteil der Anwendungsausführung im schreibgeschützten Modus liegt in der Möglichkeit, während eines umfangreichen Anwendungsupgrades eingeschränkte Funktionalität sicherzustellen.Being able to run your application in read-only mode has another side benefit – it gives you the ability to ensure limited functionality during a major application upgrade. Sie können die Anwendungsausführung im schreibgeschützten Modus auslösen, auf das sekundäre Rechenzentrum verweisen und damit sicherstellen, dass niemand auf die Daten in der primären Region zugreift, während Sie Upgrades vornehmen.You can trigger your application to run in read-only mode and point to the secondary data center, ensuring nobody is accessing the data in the primary region while you're making upgrades.

Verarbeiten von Aktualisierungen bei der Ausführung im schreibgeschützten ModusHandling updates when running in read-only mode

Es gibt viele Möglichkeiten, Aktualisierungsanforderungen bei der Ausführung im schreibgeschützten Modus zu verarbeiten.There are many ways to handle update requests when running in read-only mode. Dies wird hier nicht umfassend beschrieben, aber es gibt im Allgemeinen eine Reihe von Mustern, die Sie berücksichtigen sollten.We won't cover this comprehensively, but generally, there are a couple of patterns that you consider.

  1. Sie können auf Ihren Benutzer reagieren und ihm erläutern, dass derzeit keine Aktualisierungen akzeptiert werden.You can respond to your user and tell them you are not currently accepting updates. Mit einem Kontaktverwaltungssystem könnten Kunden beispielsweise auf Kontaktinformationen zugreifen, jedoch keine Aktualisierungen vornehmen.For example, a contact management system could enable customers to access contact information but not make updates.

  2. Sie können die Aktualisierungen in einer anderen Region der Warteschlange hinzufügen.You can enqueue your updates in another region. In diesem Fall schreiben Sie die ausstehende Aktualisierungsanforderung in eine Warteschlange einer anderen Region und haben dadurch eine Möglichkeit, diese Anforderungen zu verarbeiten, wenn das primäre Rechenzentrum wieder online geschaltet wird.In this case, you would write your pending update requests to a queue in a different region, and then have a way to process those requests after the primary data center comes online again. In diesem Szenario sollten Sie den Kunden darüber informieren, dass sich die angeforderte Aktualisierung für die spätere Verarbeitung in der Warteschlange befindet.In this scenario, you should let the customer know that the update requested is queued for later processing.

  3. Sie können Ihre Aktualisierungen in ein Speicherkonto in einer anderen Region schreiben.You can write your updates to a storage account in another region. Wenn das primäre Rechenzentrum wieder online geschaltet wird, haben Sie die Möglichkeit, diese Aktualisierungen je nach Datenstruktur mit den primären Daten zusammenzuführen.Then when the primary data center comes back online, you can have a way to merge those updates into the primary data, depending on the structure of the data. Wenn Sie beispielsweise separate Dateien mit einem Datums-/Zeitstempel im Namen erstellen, können Sie die Dateien zur primären Region kopieren.For example, if you are creating separate files with a date/time stamp in the name, you can copy those files back to the primary region. Dies funktioniert für einige Workloads wie z.B. Protokollierung und IoT-Daten.This works for some workloads such as logging and iOT data.

Verarbeiten von WiederholungsversuchenHandling retries

Mit der Azure Storage-Clientbibliothek können Sie feststellen, für welche Fehler Wiederholungsversuche ausgeführt werden können.The Azure Storage client library helps you determine which errors can be retried. Für einen 404-Fehler (Ressource nicht gefunden) kann beispielsweise ein Wiederholungsversuch ausgeführt werden, da eine Wiederholung wahrscheinlich nicht erfolgreich ist.For example, a 404 error (resource not found) can be retried because retrying it is not likely to result in success. Andererseits kann für einen 500-Fehler ein Wiederholungsversuch ausgeführt werden, da es sich um einen Serverfehler handelt und möglicherweise einfach ein vorübergehendes Problem vorliegt.On the other hand, a 500 error cannot be retried because it is a server error, and it may simply be a transient issue. Weitere Informationen finden Sie im Open-Source-Code für die ExponentialRetry-Klasse in der Speicherclientbibliothek für .NET.For more details, check out the open source code for the ExponentialRetry class in the .NET storage client library. (Suchen Sie nach der ShouldRetry-Methode.)(Look for the ShouldRetry method.)

LeseanforderungenRead requests

Leseanforderungen können in den sekundären Speicher umgeleitet werden, wenn ein Problem mit dem primären Speicher vorliegt.Read requests can be redirected to secondary storage if there is a problem with primary storage. Wie oben unter Verwenden von letztendlich konsistenten Daten beschrieben, muss Ihre Anwendung das Lesen möglicherweise veralteter Daten zulassen.As noted above in Using Eventually Consistent Data, it must be acceptable for your application to potentially read stale data. Wenn Sie die Speicherclientbibliothek für den Zugriff auf Daten aus der sekundären Region verwenden, können Sie das Wiederholungsverhalten einer Leseanforderung angeben, indem Sie einen der folgenden Werte für die LocationMode-Eigenschaft festlegen:If you are using the storage client library to access data from the secondary, you can specify the retry behavior of a read request by setting a value for the LocationMode property to one of the following:

  • PrimaryOnly (Standard)PrimaryOnly (the default)

  • PrimaryThenSecondaryPrimaryThenSecondary

  • SecondaryOnlySecondaryOnly

  • SecondaryThenPrimarySecondaryThenPrimary

Wenn Sie LocationMode auf PrimaryThenSecondary festlegen und bei der ursprünglichen Leseanforderung an den primären Endpunkt ein Fehler auftritt, für den ein Wiederholungsversuch ausgeführt werden kann, führt der Client automatisch eine weitere Leseanforderung an den sekundären Endpunkt aus.When you set the LocationMode to PrimaryThenSecondary, if the initial read request to the primary endpoint fails with an error that can be retried, the client automatically makes another read request to the secondary endpoint. Wenn es sich beim Fehler um ein Servertimeout handelt, muss der Client warten, bis das Timeout abläuft, bevor er einen wiederholbaren Fehler vom Dienst empfängt.If the error is a server timeout, then the client will have to wait for the timeout to expire before it receives a retryable error from the service.

Es gibt im Grunde zwei zu berücksichtigende Szenarien bei der Reaktion auf einen wiederholbaren Fehler:There are basically two scenarios to consider when you are deciding how to respond to a retryable error:

  • Dies ist ein isoliertes Problem, und nachfolgende Anforderungen an den primären Endpunkt geben keinen wiederholbaren Fehler zurück.This is an isolated problem and subsequent requests to the primary endpoint will not return a retryable error. Dies kann beispielsweise vorkommen, wenn ein vorübergehender Netzwerkfehler vorliegt.An example of where this might happen is when there is a transient network error.

    In diesem Szenario entstehen keine signifikanten Leistungseinbußen dadurch, dass LocationMode auf PrimaryThenSecondary festgelegt wird, da dies nur selten vorkommt.In this scenario, there is no significant performance penalty in having LocationMode set to PrimaryThenSecondary as this only happens infrequently.

  • Es handelt sich um ein Problem mit mindestens einem der Speicherdienste in der primären Region, und alle nachfolgenden Anforderungen an diesen Dienst in der primären Region geben wahrscheinlich für eine bestimmte Zeit einen wiederholbaren Fehler zurück.This is a problem with at least one of the storage services in the primary region and all subsequent requests to that service in the primary region are likely to return retryable errors for a period of time. Dies kann beispielsweise vorkommen, wenn auf die primäre Region absolut nicht zugegriffen werden kann.An example of this is if the primary region is completely inaccessible.

    In diesem Szenario treten Leistungseinbußen auf, da alle Leseanforderungen zunächst auf dem primären Endpunkt ausgeführt werden, dann warten, bis das Timeout abläuft, und anschließend zum sekundären Endpunkt wechseln.In this scenario, there is a performance penalty because all your read requests will try the primary endpoint first, wait for the timeout to expire, then switch to the secondary endpoint.

Für diese Szenarien sollten Sie feststellen, ob es ein fortlaufendes Problem mit dem primären Endpunkt gibt, und alle Leseanforderungen direkt an den sekundären Endpunkt senden, indem Sie die LocationMode-Eigenschaft auf SecondaryOnly festlegen.For these scenarios, you should identify that there is an ongoing issue with the primary endpoint and send all read requests directly to the secondary endpoint by setting the LocationMode property to SecondaryOnly. Zu diesem Zeitpunkt sollten Sie die Anwendung auch auf die Ausführung im schreibgeschützten Modus festlegen.At this time, you should also change the application to run in read-only mode. Dieser Ansatz wird als Trennschalter-Muster bezeichnet.This approach is known as the Circuit Breaker Pattern.

Aktualisieren von AnforderungenUpdate requests

Das Trennschalter-Muster kann auch auf Aktualisierungsanforderungen angewendet werden.The Circuit Breaker pattern can also be applied to update requests. Aktualisierungsanforderungen können jedoch nicht in den sekundären Speicher umgeleitet werden, da dieser schreibgeschützt ist.However, update requests cannot be redirected to secondary storage, which is read-only. Sie sollten für diese Anforderungen den LocationMode-Eigenschaftensatz auf PrimaryOnly (Standard) belassen.For these requests, you should leave the LocationMode property set to PrimaryOnly (the default). Um diese Fehler zu verarbeiten, können Sie eine Metrik auf diese Anforderungen anwenden, z.B. 10 Fehler hintereinander, und wenn der Schwellenwert erreicht wird, überführen Sie die Anwendung in den schreibgeschützten Modus.To handle these errors, you can apply a metric to these requests – such as 10 failures in a row – and when your threshold is met, switch the application into read-only mode. Sie können die im nächsten Abschnitt über Trennschalter-Muster beschriebenen Methoden auch zum Zurückkehren in den Aktualisierungsmodus verwenden.You can use the same methods for returning to update mode as those described below in the next section about the Circuit Breaker pattern.

Trennschalter-MusterCircuit Breaker pattern

Durch die Verwendung eines Trennschalter-Musters in Ihrer Anwendung können Sie verhindern, dass ein Vorgang wiederholt wird, bei dem vermutlich erneut ein Fehler auftritt.Using the Circuit Breaker pattern in your application can prevent it from retrying an operation that is likely to fail repeatedly. Die Anwendung kann weiterhin ausgeführt werden, anstatt Zeit in Anspruch zu nehmen, während der Vorgang fortlaufend exponentiell wiederholt wird.It allows the application to continue to run rather than taking up time while the operation is retried exponentially. Außerdem erkennt das Muster, wenn der Fehler behoben wurde. Zu diesem Zeitpunkt kann die Anwendung den Vorgang erneut versuchen.It also detects when the fault has been fixed, at which time the application can try the operation again.

So implementieren Sie das Trennschalter-MusterHow to implement the circuit breaker pattern

Um festzustellen, ob ein fortlaufendes Problem mit einem primären Endpunkt vorliegt, können Sie überwachen, wie häufig der Client Fehlerwiederholungen erkennt.To identify that there is an ongoing problem with a primary endpoint, you can monitor how frequently the client encounters retryable errors. Da jeder Fall unterschiedlich ist, müssen Sie den Schwellenwert für den Wechsel zum sekundären Endpunkt und zum Ausführen der Anwendung im schreibgeschützten Modus festlegen.Because each case is different, you have to decide on the threshold you want to use for the decision to switch to the secondary endpoint and run the application in read-only mode. Beispielsweise können Sie den Wechsel ausführen, wenn 10 Fehler hintereinander aufgetreten sind.For example, you could decide to perform the switch if there are 10 failures in a row with no successes. Ein weiteres Beispiel ist, zu wechseln, wenn bei 90 % der Anforderungen in einem Zeitraum von 2 Minuten Fehler auftreten.Another example is to switch if 90% of the requests in a 2-minute period fail.

Für das erste Szenario können Sie einfach die Anzahl der Fehler verwenden. Bei einem Erfolg vor Erreichen des Maximalwerts wird der Zähler auf null zurückgesetzt.For the first scenario, you can simply keep a count of the failures, and if there is a success before reaching the maximum, set the count back to zero. Für das zweite Szenario besteht die Möglichkeit zur Implementierung des MemoryCache-Objekts (in .NET).For the second scenario, one way to implement it is to use the MemoryCache object (in .NET). Für jede Anforderung fügen Sie dem Cache ein CacheItem hinzu, bestimmen den Wert für Erfolg (1) oder Fehler (0) und legen die Ablaufzeit auf 2 Minuten ab dem jetzigen Zeitpunkt fest (je nach gewünschter Zeiteinschränkung).For each request, add a CacheItem to the cache, set the value to success (1) or fail (0), and set the expiration time to 2 minutes from now (or whatever your time constraint is). Wenn ein Eintrag abläuft, wird der Eintrag automatisch entfernt.When an entry's expiration time is reached, the entry is automatically removed. Dadurch erhalten Sie ein laufendes 2-Minuten-Fenster.This will give you a rolling 2-minute window. Jedes Mal, wenn Sie eine Anforderung an den Speicherdienst übermitteln, stellen Sie zuerst eine Linq-Abfrage an das MemoryCache-Objekt, um den Erfolg in Prozent zu berechnen, indem die Werte addiert und die Summe durch die Anzahl geteilt wird.Each time you make a request to the storage service, you first use a Linq query across the MemoryCache object to calculate the percent success by summing the values and dividing by the count. Wenn der Erfolg in Prozent unter einen Schwellenwert (z.B. 10 %) fällt, legen Sie die LocationMode-Eigenschaft für Leseanforderungen auf SecondaryOnly fest und überführen die Anwendung in den schreibgeschützten Modus, bevor Sie fortfahren.When the percent success drops below some threshold (such as 10%), set the LocationMode property for read requests to SecondaryOnly and switch the application into read-only mode before continuing.

Die Fehlerschwellenwerte, die zum Bestimmen des Wechsels verwendet werden, unterscheiden sich je nach den Diensten Ihrer Anwendung. Daher sollten Sie in Erwägung ziehen, diese zu konfigurierbaren Parametern zu machen.The threshold of errors used to determine when to make the switch may vary from service to service in your application, so you should consider making them configurable parameters. An dieser Stelle entscheiden Sie auch, ob wiederholbare Fehler von jedem Dienst getrennt oder gemeinsam verarbeitet werden, wie zuvor erläutert.This is also where you decide to handle retryable errors from each service separately or as one, as discussed previously.

Ein weiterer Aspekt ist, wie mehrere Instanzen einer Anwendung verarbeitet werden und wie vorgegangen wird, wenn in den einzelnen Instanzen wiederholbare Fehler erkannt werden.Another consideration is how to handle multiple instances of an application, and what to do when you detect retryable errors in each instance. Gehen wir beispielsweise davon aus, dass 20 VMs mit der gleichen geladenen Anwendung ausführen.For example, you may have 20 VMs running with the same application loaded. Verarbeiten Sie jede Instanz separat?Do you handle each instance separately? Wenn in einer Instanz Probleme auftreten, möchten Sie die Reaktion auf nur eine Instanz beschränken, oder sollen alle Instanzen gleichartig reagieren?If one instance starts having problems, do you want to limit the response to just that one instance, or do you want to try to have all instances respond in the same way when one instance has a problem? Die getrennte Verarbeitung von Instanzen ist deutlich einfacher als eine koordinierte Reaktion. Die Vorgehensweise hängt jedoch von der Architektur Ihrer Anwendung ab.Handling the instances separately is much simpler than trying to coordinate the response across them, but how you do this depends on your application's architecture.

Optionen zur Überwachung der FehlerhäufigkeitOptions for monitoring the error frequency

Sie haben drei Hauptoptionen für die Überwachung der Fehlerhäufigkeit in der primären Region, mit denen Sie bestimmen können, wann der Wechsel zur sekundären Region und in den schreibgeschützten Modus der Anwendung stattfindet.You have three main options for monitoring the frequency of retries in the primary region in order to determine when to switch over to the secondary region and change the application to run in read-only mode.

  • Fügen Sie dem OperationContext-Objekt, das Sie an die Speicheranforderungen übergeben, einen Handler für das Wiederholungsereignis hinzu – dies ist die Methode, die in diesem Artikel erläutert und im zugehörigen Beispiel verwendet wird.Add a handler for the Retrying event on the OperationContext object you pass to your storage requests – this is the method displayed in this article and used in the accompanying sample. Diese Ereignisse werden ausgelöst, wenn der Client eine Anforderung wiederholt. Dadurch können Sie verfolgen, wie oft der Client wiederholbare Fehler auf einem primären Endpunkt feststellt.These events fire whenever the client retries a request, enabling you to track how often the client encounters retryable errors on a primary endpoint.

    operationContext.Retrying += (sender, arguments) =>
    {
        // Retrying in the primary region
        if (arguments.Request.Host == primaryhostname)
            ...
    };
    
  • In der Methode Evaluieren in einer benutzerdefinierten Wiederholungsrichtlinie können Sie benutzerdefinierten Code ausführen, sobald ein erneuter Versuch stattfindet.In the Evaluate method in a custom retry policy, you can run custom code whenever a retry takes place. Zusätzlich zur Erfassung des Zeitpunkts einer Wiederholung erhalten Sie auch die Möglichkeit, das Wiederholungsverhalten zu ändern.In addition to recording when a retry happens, this also gives you the opportunity to modify your retry behavior.

    public RetryInfo Evaluate(RetryContext retryContext,
    OperationContext operationContext)
    {
        var statusCode = retryContext.LastRequestResult.HttpStatusCode;
        if (retryContext.CurrentRetryCount >= this.maximumAttempts
            || ((statusCode >= 300 && statusCode < 500 && statusCode != 408)
            || statusCode == 501 // Not Implemented
            || statusCode == 505 // Version Not Supported
            ))
        {
            // Do not retry
            return null;
        }
    
        // Monitor retries in the primary location
        ...
    
        // Determine RetryInterval and TargetLocation
        RetryInfo info =
            CreateRetryInfo(retryContext.CurrentRetryCount);
    
        return info;
    }
    
  • Der dritte Ansatz besteht darin, eine benutzerdefinierte Komponente in der Anwendung zu implementieren, die fortlaufend Ping-Nachrichten mit leeren Leseanforderungen (z.B. das Lesen eines kleinen Blobs) an den primären Speicherendpunkt sendet, um den Systemzustand zu ermitteln.The third approach is to implement a custom monitoring component in your application that continually pings your primary storage endpoint with dummy read requests (such as reading a small blob) to determine its health. Dies nimmt zwar einige Ressourcen in Anspruch, jedoch in einem unerheblichen Maß.This would take up some resources, but not a significant amount. Wenn ein Problem festgestellt wird, durch das der Schwellenwert erreicht wird, führen Sie einen Wechsel in den schreibgeschützten Modus SecondaryOnly durch.When a problem is discovered that reaches your threshold, you would then perform the switch to SecondaryOnly and read-only mode.

Zu einem späteren Zeitpunkt möchten Sie wahrscheinlich zum primären Endpunkt zurückwechseln und Aktualisierungen wieder zulassen.At some point, you will want to switch back to using the primary endpoint and allowing updates. Wenn Sie eine der ersten beiden oben aufgeführten Methoden verwenden, können Sie einfach zurück zum primären Endpunkt wechseln und den Aktualisierungsmodus nach einem beliebig gewählten Zeitraum oder einer Anzahl von Vorgängen aktivieren.If using one of the first two methods listed above, you could simply switch back to the primary endpoint and enable update mode after an arbitrarily selected amount of time or number of operations has been performed. Anschließend können Sie die Wiederholungslogik erneut ausführen lassen.You can then let it go through the retry logic again. Wenn das Problem behoben wurde, wird der primäre Endpunkt weiterhin verwendet, und Aktualisierungen werden zugelassen.If the problem has been fixed, it will continue to use the primary endpoint and allow updates. Wenn weiterhin ein Problem vorliegt, wird erneut zum sekundären Endpunkt und in den schreibgeschützten Modus gewechselt, nachdem die festgelegten Fehlerkriterien nicht erfüllt wurden.If there is still a problem, it will once more switch back to the secondary endpoint and read-only mode after failing the criteria you've set.

Wenn im dritten Szenario die Ping-Nachricht an den primären Speicherendpunkt erfolgreich ist, können Sie den Wechsel zurück zu PrimaryOnly auslösen und weiterhin Aktualisierungen zulassen.For the third scenario, when pinging the primary storage endpoint becomes successful again, you can trigger the switch back to PrimaryOnly and continue allowing updates.

Verarbeiten von letztendlich konsistenten DatenHandling eventually consistent data

Georedundanter Speicher funktioniert durch die Replikation von Transaktionen von der primären zur sekundären Region.Geo-redundant storage works by replicating transactions from the primary to the secondary region. Dieser Replikationsprozess garantiert, dass die Daten in der sekundären Region letztendlich konsistent sind.This replication process guarantees that the data in the secondary region is eventually consistent. Das heißt, dass alle Transaktionen in der primären Region letztendlich in der sekundären Region angezeigt werden, wobei jedoch möglicherweise eine Verzögerung vor der Anzeige auftritt, und es gibt keine Garantie dafür, dass die Transaktionen in der sekundären Region in der gleichen Reihenfolge wie in der ursprünglichen Reihenfolge der primären Region eintreffen.This means that all the transactions in the primary region will eventually appear in the secondary region, but that there may be a lag before they appear, and that there is no guarantee the transactions arrive in the secondary region in the same order as that in which they were originally applied in the primary region. Wenn die Transaktionen nicht in der richtigen Reihenfolge in der sekundären Region eintreffen, können Sie möglicherweise davon ausgehen, dass die Daten in der sekundären Region inkonsistent sind, bis der Dienst auf dem aktuellen Stand ist.If your transactions arrive in the secondary region out of order, you may consider your data in the secondary region to be in an inconsistent state until the service catches up.

Die folgende Tabelle zeigt ein Beispiel dafür, was passieren kann, wenn Sie die Details einer Mitarbeiterin aktualisieren, um sie zu einem Mitglied der Rolle Administratoren zu machen.The following table shows an example of what might happen when you update the details of an employee to make them a member of the administrators role. Für dieses Beispiel müssen Sie die Mitarbeiterentität und eine Administratorrollenentität mit der Gesamtanzahl der Administratoren aktualisieren.For the sake of this example, this requires you update the employee entity and update an administrator role entity with a count of the total number of administrators. Beachten Sie, dass die Aktualisierungen in der sekundären Region in falscher Reihenfolge angewendet werden.Notice how the updates are applied out of order in the secondary region.

TimeTime TransaktionTransaction ReplikationReplication Zeitpunkt der letzten SynchronisierungLast Sync Time ErgebnisResult
T0T0 Transaktion A:Transaction A:
MitarbeiterentitätInsert employee
in primäre Region einfügenentity in primary
Transaktion A in primäre Region eingefügt,Transaction A inserted to primary,
noch nicht repliziert.not replicated yet.
T1T1 Transaktion ATransaction A
in sekundäre Regionreplicated to
repliziertsecondary
T1T1 Transaktion A in sekundäre Region repliziert.Transaction A replicated to secondary.
Zeitpunkt der letzten Synchronisierung aktualisiert.Last Sync Time updated.
T2T2 Transaktion B:Transaction B:
AktualisierenUpdate
Mitarbeiterentitätemployee entity
in primärer Regionin primary
T1T1 Transaktion B in primäre Region geschrieben,Transaction B written to primary,
noch nicht repliziert.not replicated yet.
T3T3 Transaktion C:Transaction C:
AktualisierenUpdate
administratoradministrator
Rollenentität inrole entity in
primaryprimary
T1T1 Transaktion C in primäre Region geschrieben,Transaction C written to primary,
noch nicht repliziert.not replicated yet.
T4T4 Transaktion CTransaction C
in sekundäre Regionreplicated to
repliziertsecondary
T1T1 Transaktion C in sekundäre Region repliziert.Transaction C replicated to secondary.
LastSyncTime nicht aktualisiert, daLastSyncTime not updated because
Transaktion B noch nicht repliziert wurde.transaction B has not been replicated yet.
T5T5 Entitäten aus sekundärerRead entities
Region gelesenfrom secondary
T1T1 Sie erhalten den veralteten Wert für die Mitarbeiterentität,You get the stale value for employee
da die Transaktion B nochentity because transaction B hasn't
nicht repliziert wurde.replicated yet. Sie erhalten den neuen Wert fürYou get the new value for
die Administratorrollenentität, da Cadministrator role entity because C has
repliziert wurde.replicated. Zeitpunkt der letzten Synchronisierung wurde noch nichtLast Sync Time still hasn't
aktualisiert, da die Transaktion B noch nichtbeen updated because transaction B
repliziert wurde.hasn't replicated. Sie können erkennen, dass dieYou can tell the
Administratorrollenentität inkonsistent ist, daadministrator role entity is inconsistent
Datum und Uhrzeit der Entität nach dem Zeitpunktbecause the entity date/time is after
der letzten Synchronisierung liegen.the Last Sync Time.
T6T6 Transaktion BTransaction B
in sekundäre Regionreplicated to
repliziertsecondary
T6T6 T6 – alle Transaktionen bis C wurdenT6 – All transactions through C have
repliziert, Zeitpunkt der letzten Synchronisierungbeen replicated, Last Sync Time
wurde aktualisiert.is updated.

In diesem Beispiel wird davon ausgegangen, dass der Client bei T5 zum Lesen aus der sekundären Region wechselt.In this example, assume the client switches to reading from the secondary region at T5. Er kann die Administratorrollenentität zu diesem Zeitpunkt erfolgreich lesen, die Entität enthält jedoch einen Wert für die Anzahl der Administratoren, die nicht konsistent mit der Anzahl der Mitarbeiterentitäten ist, die zu diesem Zeitpunkt in der sekundären Region als Administratoren gekennzeichnet sind.It can successfully read the administrator role entity at this time, but the entity contains a value for the count of administrators that is not consistent with the number of employee entities that are marked as administrators in the secondary region at this time. Der Client konnte diesen Wert anzeigen, es besteht jedoch das Risiko, dass es sich um inkonsistente Informationen handelt.Your client could simply display this value, with the risk that it is inconsistent information. Wahlweise kann der Client versuchen, festzustellen, ob die Administratorrolle möglicherweise inkonsistent ist, da die Aktualisierungen nicht in der richtigen Reihenfolge vorliegen, und anschließend können die Benutzer über diese Tatsache informiert werden.Alternatively, the client could attempt to determine that the administrator role is in a potentially inconsistent state because the updates have happened out of order, and then inform the user of this fact.

Um möglicherweise inkonsistente Daten zu erkennen, kann der Client den Wert des Zeitpunkts der letzten Synchronisierung verwenden, den Sie jederzeit durch eine Abfrage eines Speicherdiensts abrufen können.To recognize that it has potentially inconsistent data, the client can use the value of the Last Sync Time that you can get at any time by querying a storage service. Dadurch können Sie den Zeitpunkt der letzten Datenkonsistenz in der sekundären Region und den Zeitpunkt feststellen, zu dem der Dienst alle Transaktionen vor diesem Zeitpunkt angewendet hat.This tells you the time when the data in the secondary region was last consistent and when the service had applied all the transactions prior to that point in time. Im Beispiel oben wird nach dem Einfügen der Mitarbeiterentität in der sekundären Region durch den Dienst der Zeitpunkt der letzten Synchronisierung auf T1 festgelegt.In the example shown above, after the service inserts the employee entity in the secondary region, the last sync time is set to T1. Der Wert bleibt T1, bis der Dienst die Mitarbeiterentität in der sekundären Region aktualisiert, sobald sie auf T6 festgelegt wird.It remains at T1 until the service updates the employee entity in the secondary region when it is set to T6. Wenn der Client den Zeitpunkt der letzten Synchronisierung beim Lesen der Entität bei T5 abruft, kann dieser ihn mit dem Zeitstempel der Entität vergleichen.If the client retrieves the last sync time when it reads the entity at T5, it can compare it with the timestamp on the entity. Wenn der Zeitstempel der Entität nach dem Zeitpunkt der letzten Synchronisierung liegt, ist die Entität möglicherweise inkonsistent, und Sie können die entsprechende Aktion für Ihre Anwendung ausführen.If the timestamp on the entity is later than the last sync time, then the entity is in a potentially inconsistent state, and you can take whatever is the appropriate action for your application. Die Verwendung dieses Felds erfordert, dass Sie wissen, wann die letzte Aktualisierung des primären Replikats abgeschlossen wurde.Using this field requires that you know when the last update to the primary was completed.

Abrufen des Zeitpunkts der letzten SynchronisierungGetting the last sync time

Sie können den Zeitpunkt der letzten Synchronisierung mithilfe von PowerShell oder der Azure CLI abrufen, um festzustellen, wann das letzte Mal Daten in die sekundäre Region geschrieben wurden.You can use PowerShell or Azure CLI to retrieve the last sync time to determine when data was last written to the secondary.

PowerShellPowerShell

Um die letzte Synchronisierungszeit für das Speicherkonto mit PowerShell abzurufen, installieren Sie ein Azure Storage-Vorschaumodul, das das Abrufen von Georeplikationsstatistiken unterstützt. Beispiel:To get the last sync time for the storage account by using PowerShell, install an Azure Storage preview module that supports getting geo-replication stats. For example:

Install-Module Az.Storage –Repository PSGallery -RequiredVersion 1.1.1-preview –AllowPrerelease –AllowClobber –Force

Überprüfen Sie dann die Eigenschaft GeoReplicationStats.LastSyncTime des Speicherkontos.Then check the storage account's GeoReplicationStats.LastSyncTime property. Denken Sie daran, die Platzhalterwerte durch Ihre eigenen Werte zu ersetzen:Remember to replace the placeholder values with your own values:

$lastSyncTime = $(Get-AzStorageAccount -ResourceGroupName <resource-group> `
    -Name <storage-account> `
    -IncludeGeoReplicationStats).GeoReplicationStats.LastSyncTime

Azure-BefehlszeilenschnittstelleAzure CLI

Rufen Sie den Zeitpunkt der letzten Synchronisierung für das Speicherkonto mithilfe der Azure CLI ab, indem Sie die Eigenschaft geoReplicationStats.lastSyncTime des Speicherkontos überprüfen.To get the last sync time for the storage account by using Azure CLI, check the storage account's geoReplicationStats.lastSyncTime property. Verwenden Sie den Parameter --expand, um Werte für die unter geoReplicationStats geschachtelten Eigenschaften zurückzugeben.Use the --expand parameter to return values for the properties nested under geoReplicationStats. Denken Sie daran, die Platzhalterwerte durch Ihre eigenen Werte zu ersetzen:Remember to replace the placeholder values with your own values:

$lastSyncTime=$(az storage account show \
    --name <storage-account> \
    --resource-group <resource-group> \
    --expand geoReplicationStats \
    --query geoReplicationStats.lastSyncTime \
    --output tsv)

TestenTesting

Es ist wichtig, zu testen, ob Ihre Anwendung sich erwartungsgemäß verhält, wenn wiederholbare Fehler auftreten.It's important to test that your application behaves as expected when it encounters retryable errors. Beispielsweise müssen Sie testen, ob die Anwendung zur sekundären Region und in den schreibgeschützten Modus wechselt, wenn ein Problem entdeckt wird, und zurückwechselt, wenn die primäre Region wieder verfügbar ist.For example, you need to test that the application switches to the secondary and into read-only mode when it detects a problem, and switches back when the primary region becomes available again. Zu diesem Zweck benötigen Sie eine Möglichkeit zum Simulieren von wiederholbaren Fehlern und deren Auftrittshäufigkeit.To do this, you need a way to simulate retryable errors and control how often they occur.

Sie können Fiddler zum Abfangen und Bearbeiten von HTTP-Antworten in einem Skript verwenden.You can use Fiddler to intercept and modify HTTP responses in a script. Dieses Skript kann Antworten vom primären Endpunkt identifizieren und den HTTP-Statuscode in einen Statuscode ändern, den die Speicherclientbibliothek als wiederholbaren Fehler erkennt.This script can identify responses that come from your primary endpoint and change the HTTP status code to one that the Storage Client Library recognizes as a retryable error. Dieser Codeausschnitt zeigt ein einfaches Beispiel eines Fiddler-Skripts, das Antworten auf Leseanforderungen an die employeedata-Tabelle abfängt, um einen 502-Status zurückzugeben:This code snippet shows a simple example of a Fiddler script that intercepts responses to read requests against the employeedata table to return a 502 status:

static function OnBeforeResponse(oSession: Session) {
    ...
    if ((oSession.hostname == "\[yourstorageaccount\].table.core.windows.net")
      && (oSession.PathAndQuery.StartsWith("/employeedata?$filter"))) {
        oSession.responseCode = 502;
    }
}

Sie könnten dieses Beispiel erweitern, um ein größeres Spektrum an Anforderungen abzufangen, und nur den responseCode für einige Anforderungen ändern, um ein realistischeres Szenario zu simulieren.You could extend this example to intercept a wider range of requests and only change the responseCode on some of them to better simulate a real-world scenario. Weitere Informationen zum Anpassen von Fiddler-Skripts finden Sie unter Modifying a Request or Response (Ändern einer Anforderung oder Antwort) in der Fiddler-Dokumentation.For more information about customizing Fiddler scripts, see Modifying a Request or Response in the Fiddler documentation.

Wenn Sie die Schwellenwerte für den Wechsel Ihrer Anwendung in den schreibgeschützten Modus konfigurierbar gemacht haben, ist das Testen des Verhaltens anhand von Transaktionsvolumes außerhalb von Produktionsumgebungen einfacher.If you have made the thresholds for switching your application to read-only mode configurable, it will be easier to test the behavior with non-production transaction volumes.

Nächste SchritteNext Steps