Návrh vysoce dostupných aplikací s využitím geograficky redundantního úložiště s přístupem pro čteníDesigning highly available applications using read-access geo-redundant storage

Běžnou funkcí cloudových infrastruktur, jako je Azure Storage, je, že poskytují vysoce dostupnou platformu pro hostování aplikací.A common feature of cloud-based infrastructures like Azure Storage is that they provide a highly available platform for hosting applications. Vývojáři cloudových aplikací musí pečlivě zvážit, jak tuto platformu využít k doručování vysoce dostupných aplikací svým uživatelům.Developers of cloud-based applications must consider carefully how to leverage this platform to deliver highly available applications to their users. Tento článek se zaměřuje na to, jak můžou vývojáři používat jednu z geograficky redundantních možností replikace Azure a zajistit, aby jejich aplikace Azure Storage byly vysoce dostupné.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.

Účty úložiště nakonfigurované pro geograficky redundantní replikaci se synchronně replikují v primární oblasti a pak se asynchronně replikují do sekundární oblasti, která je od sebe stovky kilometrů.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 nabízí dva typy geograficky redundantní replikace:Azure Storage offers two types of geo-redundant replication:

  • Geografická zóna – redundantní úložiště (GZRS) (Preview) poskytuje replikaci pro scénáře vyžadující vysokou dostupnost a maximální odolnost.Geo-zone-redundant storage (GZRS) (preview) provides replication for scenarios requiring both high availability and maximum durability. Data se replikují synchronně v rámci tří zón dostupnosti Azure v primární oblasti pomocí redundantního úložiště (ZRS) zóny a pak se asynchronně replikují do sekundární oblasti.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. Pro přístup pro čtení dat v sekundární oblasti povolte přístup pro čtení Geo-Zone-redundantní úložiště (RA-GZRS).For read access to data in the secondary region, enable read-access geo-zone-redundant storage (RA-GZRS).
  • Geograficky redundantní úložiště (GRS) zajišťuje meziregionální replikaci pro ochranu před místními výpadky.Geo-redundant storage (GRS) provides cross-regional replication to protect against regional outages. Data se replikují synchronně třikrát v primární oblasti pomocí místně redundantního úložiště (LRS) a pak se asynchronně replikují do sekundární oblasti.Data is replicated synchronously three times in the primary region using locally redundant storage (LRS), then replicated asynchronously to the secondary region. Pro přístup pro čtení dat v sekundární oblasti povolte geograficky redundantní úložiště s přístupem pro čtení (RA-GRS).For read access to data in the secondary region, enable read-access geo-redundant storage (RA-GRS).

V tomto článku se dozvíte, jak navrhnout aplikaci pro zpracování výpadku v primární oblasti.This article shows how to design your application to handle an outage in the primary region. Pokud primární oblast nebude k dispozici, může být aplikace přizpůsobena provádění operací čtení v sekundární oblasti.If the primary region becomes unavailable, your application can adapt to perform read operations against the secondary region instead. Než začnete, ujistěte se, že je váš účet úložiště nakonfigurovaný pro RA-GRS nebo RA-GZRS.Make sure that your storage account is configured for RA-GRS or RA-GZRS before you get started.

Informace o tom, které primární oblasti jsou spárovány se sekundárními oblastmi , najdete v tématu provozní kontinuita a zotavení po havárii (BCDR): Spárované oblasti Azure.For information about which primary regions are paired with which secondary regions, see Business continuity and disaster recovery (BCDR): Azure Paired Regions.

V tomto článku jsou uvedené fragmenty kódu a odkaz na úplnou ukázku na konci, kterou si můžete stáhnout a spustit.There are code snippets included in this article, and a link to a complete sample at the end that you can download and run.

Požadavky na návrh aplikace při čtení ze sekundárníhoApplication design considerations when reading from the secondary

Účelem tohoto článku je Ukázat, jak navrhnout aplikaci, která bude i nadále fungovat (i když v omezené kapacitě) i v případě závažné havárie v primárním datovém centru.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. Aplikaci můžete navrhnout tak, aby zpracovávala přechodné nebo dlouhodobé problémy čtením ze sekundární oblasti, když dojde k problému, který je v konfliktu se čtením z primární oblasti.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. Když je primární oblast opět k dispozici, vaše aplikace se může vrátit ke čtení z primární oblasti.When the primary region is available again, your application can return to reading from the primary region.

Při návrhu aplikace pro RA-GRS nebo RA-GZRS mějte na paměti tyto klíčové body:Keep in mind these key points when designing your application for RA-GRS or RA-GZRS:

  • Azure Storage uchovává kopii dat, která ukládáte do primární oblasti v sekundární oblasti, jen pro čtení.Azure Storage maintains a read-only copy of the data you store in your primary region in a secondary region. Jak je uvedeno výše, služba úložiště Určuje umístění sekundární oblasti.As noted above, the storage service determines the location of the secondary region.

  • Kopie, která je jen pro čtení, je nakonec konzistentní s daty v primární oblasti.The read-only copy is eventually consistent with the data in the primary region.

  • U objektů blob, tabulek a front můžete zadat dotaz na sekundární oblast pro hodnotu čas poslední synchronizace , která oznamuje, že došlo k poslední replikaci z primární do sekundární oblasti.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. (To není podporováno u souborů Azure, které v tuto chvíli nemají redundanci RA-GRS.)(This is not supported for Azure Files, which doesn't have RA-GRS redundancy at this time.)

  • Pomocí klientské knihovny pro úložiště můžete číst a zapisovat data buď v primární nebo sekundární oblasti.You can use the Storage Client Library to read and write data in either the primary or secondary region. Pokud vyprší časový limit žádosti o čtení do primární oblasti, můžete také automaticky přesměrovat požadavky na čtení do sekundární oblasti.You can also redirect read requests automatically to the secondary region if a read request to the primary region times out.

  • Pokud primární oblast nebude k dispozici, můžete iniciovat převzetí služeb při selhání účtu.If the primary region becomes unavailable, you can initiate an account failover. Při převzetí služeb při selhání do sekundární oblasti se položky DNS odkazující na primární oblast změní tak, aby odkazovaly na sekundární oblast.When you fail over to the secondary region, the DNS entries pointing to the primary region are changed to point to the secondary region. Po dokončení převzetí služeb při selhání bude pro účty GRS a RA-GRS obnovený přístup pro zápis.After the failover is complete, write access is restored for GRS and RA-GRS accounts. Další informace najdete v tématu obnovení po havárii a převzetí služeb při selhání účtu úložiště (Preview) v Azure Storage.For more information, see Disaster recovery and storage account failover (preview) in Azure Storage.

Poznámka

Převzetí služeb při selhání účtu spravovaného zákazníkem (Preview) ještě není dostupné v oblastech podporujících GZRS/RA-GZRS, takže zákazníci momentálně nemůžou spravovat události převzetí služeb při selhání účtu s GZRS a RA-GZRS účty.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. V průběhu verze Preview bude společnost Microsoft spravovat všechny události převzetí služeb při selhání, které mají vliv na účty GZRS/RA-GZRS.During the preview, Microsoft will manage any failover events affecting GZRS/RA-GZRS accounts.

Použití nakonec konzistentních datUsing eventually consistent data

Navrhované řešení předpokládá, že je přijatelné vracet potenciálně zastaralá data do volající aplikace.The proposed solution assumes that it is acceptable to return potentially stale data to the calling application. Vzhledem k tomu, že data v sekundární oblasti jsou nakonec konzistentní, je možné, že primární oblast nebude přístupná, než se dokončí aktualizace sekundární oblasti.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.

Předpokládejme například, že zákazník úspěšně odeslal aktualizaci, ale primární region se nezdaří před tím, než se aktualizace rozšíří do sekundární oblasti.For example, suppose your customer submits an update successfully, but the primary region fails before the update is propagated to the secondary region. Když zákazník požádá o čtení dat zpět, obdrží ze sekundární oblasti místo aktualizovaných dat zastaralá data.When the customer asks to read the data back, they receive the stale data from the secondary region instead of the updated data. Při návrhu aplikace se musíte rozhodnout, jestli je to přijatelné, a pokud ano, jak se bude zákazník považovat za zprávu.When designing your application, you must decide whether this is acceptable, and if so, how you will message the customer.

Později v tomto článku ukážeme, jak kontrolovat čas poslední synchronizace pro sekundární data a ověřit, jestli je sekundární je aktuální.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.

Zpracování služeb samostatně nebo dohromadyHandling services separately or all together

V nepravděpodobném případě je možné, že jedna služba nebude k dispozici, zatímco ostatní služby jsou pořád plně funkční.While unlikely, it is possible for one service to become unavailable while the other services are still fully functional. Můžete zpracovávat opakované pokusy a režim jen pro čtení pro každou službu samostatně (objekty blob, fronty, tabulky) nebo můžete pokusy pokaždé pro všechny služby úložiště společně zpracovávat současně.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.

Pokud například používáte ve své aplikaci fronty a objekty blob, můžete se rozhodnout do samostatného kódu pro zpracování opakovaných chyb pro každé z nich.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. Pokud se pak znovu pokusíte ze služby BLOB Service, ale i nadále funguje, bude to mít vliv jenom na součást aplikace, která zpracovává objekty blob.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. Pokud se rozhodnete všechny opakované pokusy o službu úložiště zpracovat obecně a volání služby BLOB Service vrátí chybu s opakováním, bude to mít vliv na požadavky na službu BLOB Service i na službu front.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.

Nakonec závisí na složitosti vaší aplikace.Ultimately, this depends on the complexity of your application. Můžete se rozhodnout Nezpracovávat selhání podle služby, ale místo toho přesměrovat požadavky na čtení pro všechny služby úložiště do sekundární oblasti a spustit aplikaci v režimu jen pro čtení při detekci problému se službou úložiště v primární oblasti.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.

Další důležité informaceOther considerations

Toto jsou další okolnosti, které budeme projednávat ve zbývající části tohoto článku.These are the other considerations we will discuss in the rest of this article.

  • Zpracování opakovaných pokusů žádostí o čtení pomocí vzoru pro přerušení okruhuHandling retries of read requests using the Circuit Breaker pattern

  • Nakonec konzistentní data a čas poslední synchronizaceEventually-consistent data and the Last Sync Time

  • TestováníTesting

Spuštění aplikace v režimu jen pro čteníRunning your application in read-only mode

Aby bylo možné efektivně připravovat výpadek v primární oblasti, je nutné, abyste mohli zpracovávat žádosti o neúspěšné čtení i neúspěšné žádosti o aktualizaci (s aktualizací v tomto případě to znamená vložení, aktualizace a odstranění).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). Pokud dojde k chybě primární oblasti, žádosti o čtení je možné přesměrovat do sekundární oblasti.If the primary region fails, read requests can be redirected to the secondary region. Žádosti o aktualizaci ale nelze přesměrovat na sekundární, protože sekundární je jen pro čtení.However, update requests cannot be redirected to the secondary because the secondary is read-only. Z tohoto důvodu je nutné navrhnout aplikaci tak, aby běžela v režimu jen pro čtení.For this reason, you need to design your application to run in read-only mode.

Můžete například nastavit příznak, který je zkontrolován před odesláním žádostí o aktualizaci do Azure Storage.For example, you can set a flag that is checked before any update requests are submitted to Azure Storage. Pokud jeden z požadavků na aktualizaci přichází prostřednictvím, můžete ho přeskočit a vrátit se k příslušné reakci na zákazníka.When one of the update requests comes through, you can skip it and return an appropriate response to the customer. Některé funkce můžete dokonce chtít zcela vypnout, dokud se problém nevyřeší a upozorní uživatele, že tyto funkce jsou dočasně nedostupné.You may even want to disable certain features altogether until the problem is resolved and notify users that those features are temporarily unavailable.

Pokud se rozhodnete zpracovávat chyby každé služby samostatně, budete také muset zpracovat možnost spuštění aplikace v režimu jen pro čtení podle služby.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. Například můžete mít příznaky jen pro čtení pro každou službu, kterou lze povolit a zakázat.For example, you may have read-only flags for each service that can be enabled and disabled. Pak můžete příznak zpracovat na příslušných místech v kódu.Then you can handle the flag in the appropriate places in your code.

Možnost spuštění vaší aplikace v režimu jen pro čtení má další výhodu na straně druhé. díky tomu máte možnost zajistit během upgradu hlavní aplikace omezené funkce.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. Svou aplikaci můžete aktivovat tak, aby běžela v režimu jen pro čtení, odkazovala na sekundární datové centrum, takže nikdo nepřistupuje k datům v primární oblasti, když provádíte upgrade.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.

Zpracování aktualizací při spuštění v režimu jen pro čteníHandling updates when running in read-only mode

Existuje mnoho způsobů, jak zpracovávat žádosti o aktualizaci při spuštění v režimu jen pro čtení.There are many ways to handle update requests when running in read-only mode. Nebudeme se k tomu zabývat komplexně, ale obecně existuje několik vzorů, které považujete za vhodné.We won't cover this comprehensively, but generally, there are a couple of patterns that you consider.

  1. Můžete reagovat na uživatele a sdělit jim, že v současné době nepřijímáte aktualizace.You can respond to your user and tell them you are not currently accepting updates. Systém pro správu kontaktů by například mohl zákazníkům umožnit přístup k kontaktním údajům, ale nemůže dělat aktualizace.For example, a contact management system could enable customers to access contact information but not make updates.

  2. Aktualizace můžete zařadit do fronty v jiné oblasti.You can enqueue your updates in another region. V takovém případě zapíšete čekající žádosti o aktualizaci do fronty v jiné oblasti a potom budete mít možnost tyto požadavky zpracovat po opětovném přepnutí primárního datového centra do online režimu.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. V tomto scénáři byste měli dát zákazníkovi jistotu, že požadovaná aktualizace je zařazená do fronty pro pozdější zpracování.In this scenario, you should let the customer know that the update requested is queued for later processing.

  3. Aktualizace můžete zapsat do účtu úložiště v jiné oblasti.You can write your updates to a storage account in another region. Až se primární datové centrum vrátí do režimu online, můžete mít možnost tyto aktualizace sloučit do primárních dat v závislosti na struktuře dat.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. Pokud například vytváříte samostatné soubory s razítkem data a času v názvu, můžete tyto soubory zkopírovat zpátky do primární oblasti.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. To funguje pro některé úlohy, jako je protokolování a data iOT.This works for some workloads such as logging and iOT data.

Zpracování opakovaných pokusůHandling retries

Klientská knihovna Azure Storage vám pomůže určit, které chyby se můžou opakovat.The Azure Storage client library helps you determine which errors can be retried. Například Chyba 404 (prostředek se nepovedlo najít) se může opakovat, protože opakování nebude pravděpodobně mít za následek úspěch.For example, a 404 error (resource not found) can be retried because retrying it is not likely to result in success. Na druhé straně se chyba 500 nedá opakovat, protože se jedná o chybu serveru a může se jednat jenom o přechodný problém.On the other hand, a 500 error cannot be retried because it is a server error, and it may simply be a transient issue. Další podrobnosti najdete v kódu open source pro třídu ExponentialRetry v klientské knihovně úložiště .NET.For more details, check out the open source code for the ExponentialRetry class in the .NET storage client library. (Vyhledejte metodu ShouldRetry.)(Look for the ShouldRetry method.)

Požadavky na čteníRead requests

Pokud dojde k potížím s primárním úložištěm, můžou se požadavky na čtení přesměrovat do sekundárního úložiště.Read requests can be redirected to secondary storage if there is a problem with primary storage. Jak bylo uvedeno výše v používání trvalých dat, musí být přijatelné, aby vaše aplikace mohla číst zastaralá data.As noted above in Using Eventually Consistent Data, it must be acceptable for your application to potentially read stale data. Pokud používáte klientskou knihovnu pro úložiště pro přístup k datům ze sekundární verze, můžete určit chování opakování žádosti o čtení nastavením hodnoty vlastnosti LocationMode na jednu z následujících možností: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 (výchozí)PrimaryOnly (the default)

  • PrimaryThenSecondaryPrimaryThenSecondary

  • SecondaryOnlySecondaryOnly

  • SecondaryThenPrimarySecondaryThenPrimary

Pokud nastavíte LocationMode na PrimaryThenSecondary, pokud počáteční žádost o čtení na primární koncový bod dojde k chybě s chybou, která se dá opakovat, klient automaticky provede další požadavek na čtení sekundárního koncového bodu.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. Pokud je chyba časovým limitem serveru, bude muset klient počkat na vypršení časového limitu, než obdrží chybu, která bude možné znovu spustit ze služby.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.

Při rozhodování, jak reagovat na opakovanou chybu, je třeba zvážit v podstatě dva scénáře:There are basically two scenarios to consider when you are deciding how to respond to a retryable error:

  • Jedná se o izolovaný problém a následné požadavky na primární koncový bod nevrátí opakovanou chybu.This is an isolated problem and subsequent requests to the primary endpoint will not return a retryable error. K tomu může dojít například v případě přechodné chyby sítě.An example of where this might happen is when there is a transient network error.

    V tomto scénáři nedochází k výraznému snížení výkonu ve LocationMode nastaveném na PrimaryThenSecondary , protože k tomu dochází jenom zřídka.In this scenario, there is no significant performance penalty in having LocationMode set to PrimaryThenSecondary as this only happens infrequently.

  • Jedná se o problém s aspoň jednou ze služeb úložiště v primární oblasti a všechny následné požadavky na tuto službu v primární oblasti budou nejspíš vracet opakované chyby po určitou dobu.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. Příkladem je, že primární oblast je zcela nepřístupná.An example of this is if the primary region is completely inaccessible.

    V tomto scénáři dochází ke snížení výkonu, protože všechny žádosti o čtení nejprve vyzkouší primární koncový bod, počkejte na vypršení časového limitu a pak přepněte do sekundárního koncového bodu.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.

V těchto scénářích byste měli zjistit, jestli existuje průběžný problém s primárním koncovým bodem a poslat všechny požadavky na čtení přímo do sekundárního koncového bodu nastavením vlastnosti LocationMode na SecondaryOnly.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. V tuto chvíli byste měli aplikaci změnit také tak, aby běžela pouze v režimu jen pro čtení.At this time, you should also change the application to run in read-only mode. Tento přístup je známý jako vzorek přerušení okruhu.This approach is known as the Circuit Breaker Pattern.

Žádosti o aktualizaciUpdate requests

Pro požadavky na aktualizaci lze také použít vzor pro přerušení okruhu.The Circuit Breaker pattern can also be applied to update requests. Žádosti o aktualizaci se ale nedají přesměrovat do sekundárního úložiště, které je jen pro čtení.However, update requests cannot be redirected to secondary storage, which is read-only. Pro tyto požadavky byste měli ponechat vlastnost LocationMode nastavenou na PrimaryOnly (výchozí).For these requests, you should leave the LocationMode property set to PrimaryOnly (the default). Chcete-li tyto chyby zpracovat, můžete použít metriku na tyto požadavky – například 10 chyb na řádku – a když je prahová hodnota splněna, přepněte aplikaci do režimu jen pro čtení.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. Stejné metody můžete použít pro návrat do režimu aktualizace, jak je popsáno níže v další části o vzoru pro přerušení okruhu.You can use the same methods for returning to update mode as those described below in the next section about the Circuit Breaker pattern.

Model Jistič (Circuit Breaker)Circuit Breaker pattern

Použití vzoru pro přerušení okruhů ve vaší aplikaci může zabránit tomu, aby se znovu pokusilo o operaci, která pravděpodobně selže opakovaně.Using the Circuit Breaker pattern in your application can prevent it from retrying an operation that is likely to fail repeatedly. Umožňuje, aby aplikace pokračovala v běhu, a ne čas, kdy se operace opakuje exponenciálně.It allows the application to continue to run rather than taking up time while the operation is retried exponentially. Také zjistí, kdy byla chyba opravena, v jakém čase aplikace může operaci opakovat.It also detects when the fault has been fixed, at which time the application can try the operation again.

Postup implementace vzoru pro přerušení okruhuHow to implement the circuit breaker pattern

Chcete-li zjistit, zda se jedná o průběžný problém s primárním koncovým bodem, můžete sledovat, jak často v klientovi dojde k opakovaným chybám.To identify that there is an ongoing problem with a primary endpoint, you can monitor how frequently the client encounters retryable errors. Vzhledem k tomu, že se každý případ liší, musíte se rozhodnout na prahové hodnotě, kterou chcete použít pro rozhodnutí přepnout na sekundární koncový bod a spustit aplikaci v režimu jen pro čtení.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. Například se můžete rozhodnout provést přepínač, pokud dojde k 10 selháním v řádku bez úspěchů.For example, you could decide to perform the switch if there are 10 failures in a row with no successes. Dalším příkladem je přepnutí, pokud selže 90% žádostí v období 2 minut.Another example is to switch if 90% of the requests in a 2-minute period fail.

V prvním scénáři můžete jednoduše zachovat počet selhání a v případě úspěchu až do maximální doby nastavit počet zpět na nulu.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. V druhém scénáři je jedním ze způsobů, jak implementovat, je použít objekt MemoryCache (v rozhraní .NET).For the second scenario, one way to implement it is to use the MemoryCache object (in .NET). Pro každý požadavek přidejte do mezipaměti CacheItem., nastavte hodnotu na Success (1) nebo neúspěšná (0) a nastavte čas vypršení platnosti na 2 minuty od tohoto okamžiku (nebo podle toho, co vaše časové omezení je).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). Po dosažení doby vypršení platnosti položky je položka automaticky odebrána.When an entry's expiration time is reached, the entry is automatically removed. Tím získáte souhrnné okno se dvěma minutami.This will give you a rolling 2-minute window. Pokaždé, když vytvoříte požadavek na službu úložiště, nejprve použijete dotaz LINQ v rámci objektu MemoryCache k výpočtu procenta úspěšnosti sečtením hodnot a vydělením podle počtu.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. Pokud procento úspěšnosti klesne pod určitou prahovou hodnotu (například 10%), nastavte vlastnost LocationMode pro požadavky na čtení na SecondaryOnly a před pokračováním přepněte aplikaci do režimu jen pro čtení.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.

Prahová hodnota chyb, která se používá k určení, kdy se má přepínač lišit od služby ke službě ve vaší aplikaci, proto byste měli zvážit, že tyto parametry jsou konfigurovatelné.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. V takovém případě se také rozhodnete, že bude možné zpracovávat opakované chyby z každé služby samostatně nebo jako jednu, jak je popsáno výše.This is also where you decide to handle retryable errors from each service separately or as one, as discussed previously.

Dalším aspektem je postup, jak zpracovat více instancí aplikace a co dělat při detekci opakovaných chyb v každé instanci.Another consideration is how to handle multiple instances of an application, and what to do when you detect retryable errors in each instance. Můžete mít například 20 virtuálních počítačů spuštěných se stejnou aplikací.For example, you may have 20 VMs running with the same application loaded. Každou instanci zpracujete samostatně?Do you handle each instance separately? Pokud se u jedné instance spustí problémy, přejete si omezit reakci jenom na jednu instanci, nebo chcete zkusit, aby všechny instance odpovídaly stejným způsobem, když má jedna instance nějaký problém?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? Zpracovávání instancí samostatně je mnohem jednodušší než pokus o koordinaci odezvy napříč nimi, ale jak to uděláte, záleží na architektuře vaší aplikace.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.

Možnosti monitorování četnosti chybOptions for monitoring the error frequency

Máte tři hlavní možnosti monitorování četnosti opakování v primární oblasti, aby bylo možné určit, kdy přepnout do sekundární oblasti a změnit aplikaci tak, aby běžela v režimu jen pro čtení.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.

  • Přidejte obslužnou rutinu pro událost opakování události na objekt OperationContext , který předáte vašim požadavkům na úložiště – toto je metoda zobrazená v tomto článku a používaná v doprovodné ukázce.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. Tyto události se aktivují pokaždé, když klient opakuje požadavek, což vám umožní sledovat, jak často má klient v primárním koncovém bodě narazit opakované chyby.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)
            ...
    };
    
  • V metodě Evaluate ve vlastních zásadách opakování můžete spustit vlastní kód vždy, když dojde k opakování.In the Evaluate method in a custom retry policy, you can run custom code whenever a retry takes place. Kromě nahrávání, když dojde k opakování, vám to také umožní změnit chování při opakování.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;
    }
    
  • Třetím přístupem je implementace vlastní součásti monitorování ve vaší aplikaci, která nepřetržitě otestuje pomocí testu koncového bodu primárního úložiště (například čtení malého objektu BLOB) a určí jeho stav.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. Tím se zabere několik prostředků, ale ne značná částka.This would take up some resources, but not a significant amount. Po zjištění problému, který dosáhne vaší prahové hodnoty, byste měli přepnout do režimu SecondaryOnly a jen pro čtení.When a problem is discovered that reaches your threshold, you would then perform the switch to SecondaryOnly and read-only mode.

V určitém okamžiku budete chtít přejít zpátky k použití primárního koncového bodu a povolení aktualizací.At some point, you will want to switch back to using the primary endpoint and allowing updates. Pokud používáte jednu z prvních dvou metod uvedených výše, můžete jednoduše přejít zpátky k primárnímu koncovému bodu a povolit režim aktualizace po libovolné době zvolené doby nebo počtu operací.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. Pak můžete znovu projít logiku opakování.You can then let it go through the retry logic again. Pokud byl problém vyřešen, bude nadále používat primární koncový bod a povoluje aktualizace.If the problem has been fixed, it will continue to use the primary endpoint and allow updates. Pokud dojde k problému, bude po neúspěšném nastavování nastavených kritérií přepnut do sekundárního koncového bodu a režimu jen pro čtení.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.

V případě třetího scénáře se při opakovaném pokusu o ověření platnosti koncového bodu primárního úložiště v případě, že dojde k úspěšnému dokončení aktualizace, můžete aktivovat přepínač zpět na PrimaryOnly a pokračovat v povolování aktualizací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.

Zpracování nakonec konzistentních datHandling eventually consistent data

Geograficky redundantní úložiště funguje replikací transakcí z primární do sekundární oblasti.Geo-redundant storage works by replicating transactions from the primary to the secondary region. Tento proces replikace zaručuje, že data v sekundární oblasti jsou nakonec konzistentní.This replication process guarantees that the data in the secondary region is eventually consistent. To znamená, že se všechny transakce v primární oblasti budou nakonec zobrazovat v sekundární oblasti, ale může se stát, že se objeví prodleva předtím, než se objeví, a nezaručujeme, že transakce přicházejí do sekundární oblasti ve stejném pořadí, v jakém jsou byly původně aplikovány v primární oblasti.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. Pokud vaše transakce dorazí do sekundární oblasti mimo pořadí, můžete zvážit , že vaše data v sekundární oblasti budou v nekonzistentním stavu, dokud se služba nedostane.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.

Následující tabulka ukazuje příklad toho, co se může stát, když aktualizujete podrobnosti o zaměstnanci, abyste je mohli udělat jako členové role správců .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. V tomto příkladu je potřeba aktualizovat entitu Zaměstnanec a aktualizovat entitu role správce s počtem celkového počtu správců.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. Všimněte si, jak se aktualizace aplikují v sekundární oblasti mimo pořadí.Notice how the updates are applied out of order in the secondary region.

časTime TransakceTransaction ReplikaceReplication Čas poslední synchronizaceLast Sync Time výsledekResult
T0T0 Transakce A:Transaction A:
Vložit zaměstnanceInsert employee
entita v primárním objektuentity in primary
Transakce A vložená na primární,Transaction A inserted to primary,
ještě není replikované.not replicated yet.
T1T1 Transakce ATransaction A
replikováno doreplicated to
sekundárnísecondary
T1T1 Transakce byla replikována do sekundárního.Transaction A replicated to secondary.
Čas poslední synchronizace se aktualizoval.Last Sync Time updated.
T2T2 Transakce B:Transaction B:
AktualizaceUpdate
entita zaměstnanceemployee entity
v primárnímin primary
T1T1 Transakce B se zapsala do primárního,Transaction B written to primary,
ještě není replikované.not replicated yet.
T3T3 Transakce C:Transaction C:
AktualizaceUpdate
správceadministrator
entita role vrole entity in
primárníprimary
T1T1 Transakce C byla zapsána do primárního,Transaction C written to primary,
ještě není replikované.not replicated yet.
T4T4 Transakce CTransaction C
replikováno doreplicated to
sekundárnísecondary
T1T1 Transakce C byla replikována do sekundárního.Transaction C replicated to secondary.
LastSyncTime se neaktualizovala, protožeLastSyncTime not updated because
transakce B se ještě nereplikoval.transaction B has not been replicated yet.
T5T5 Čtení entitRead entities
ze sekundárnífrom secondary
T1T1 Získáte zastaralou hodnotu pro zaměstnance.You get the stale value for employee
entita, protože transakce B nebylaentity because transaction B hasn't
replika ještě proběhla.replicated yet. Získáte novou hodnotu proYou get the new value for
entita role správce, protože C máadministrator role entity because C has
replikovateln.replicated. Čas poslední synchronizace ještě není.Last Sync Time still hasn't
Aktualizováno, protože transakce Bbeen updated because transaction B
nereplikuje se.hasn't replicated. Můžete říct, žeYou can tell the
entita role správce je nekonzistentní.administrator role entity is inconsistent
protože je datum/čas entity pobecause the entity date/time is after
Čas poslední synchronizacethe Last Sync Time.
T6T6 Transakce BTransaction B
replikováno doreplicated to
sekundárnísecondary
T6T6 T6 – všechny transakce prostřednictvím CT6 – All transactions through C have
replikováno, čas poslední synchronizacebeen replicated, Last Sync Time
je aktualizovaný.is updated.

V tomto příkladu Předpokládejme, že klient přepne na čtení ze sekundární oblasti v T5.In this example, assume the client switches to reading from the secondary region at T5. V tuto chvíli může úspěšně číst entitu role správce , ale entita obsahuje hodnotu pro počet správců, kteří nejsou konzistentní s počtem entit zaměstnanců označených jako správci v sekundárním umístění. oblast v tomto okamžiku.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. Váš klient může jednoduše zobrazit tuto hodnotu s rizikem, že se jedná o nekonzistentní informace.Your client could simply display this value, with the risk that it is inconsistent information. Klient se případně může pokusit určit, že role správce je v potenciálně nekonzistentním stavu, protože aktualizace nastaly mimo pořadí, a pak uživatele informovat o této skutečnosti.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.

Aby bylo možné rozpoznat, že má potenciálně nekonzistentní data, může klient použít hodnotu času poslední synchronizace , kterou můžete kdykoli získat pomocí dotazu na službu úložiště.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. Tím se dozvíte čas, kdy byla data v sekundární oblasti naposledy konzistentní a kdy služba použila všechny transakce před tímto bodem v čase.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. V příkladu uvedeném výše služba vloží entitu Zaměstnanec do sekundární oblasti, čas poslední synchronizace se nastaví na T1.In the example shown above, after the service inserts the employee entity in the secondary region, the last sync time is set to T1. Zůstane v T1 , dokud služba neaktualizuje entitu Zaměstnanec v sekundární oblasti, když je nastavená na T6.It remains at T1 until the service updates the employee entity in the secondary region when it is set to T6. Pokud klient načte čas poslední synchronizace při čtení entity v T5, může ji porovnat s časovým razítkem v entitě.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. Pokud je časové razítko v entitě pozdější než čas poslední synchronizace, pak je entita v potenciálně nekonzistentním stavu a můžete to provést, pokud je pro vaši aplikaci vhodná akce.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. Použití tohoto pole vyžaduje, abyste věděli, kdy byla poslední aktualizace k primárnímu dokončení dokončena.Using this field requires that you know when the last update to the primary was completed.

Načítá se čas poslední synchronizace.Getting the last sync time

Pomocí PowerShellu nebo rozhraní příkazového řádku Azure můžete načíst čas poslední synchronizace a určit, kdy byla data naposledy zapsána do sekundárního.You can use PowerShell or Azure CLI to retrieve the last sync time to determine when data was last written to the secondary.

PowerShellPowerShell

Pokud chcete získat čas poslední synchronizace pro účet úložiště pomocí PowerShellu, nainstalujte modul Azure Storage Preview, který podporuje získávání statistik geografické replikace. Příklad: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

Pak zkontrolujte vlastnost GeoReplicationStats. LastSyncTime účtu úložiště.Then check the storage account's GeoReplicationStats.LastSyncTime property. Nezapomeňte nahradit hodnoty zástupných symbolů vlastními hodnotami:Remember to replace the placeholder values with your own values:

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

Azure CLIAzure CLI

Pokud chcete získat čas poslední synchronizace pro účet úložiště pomocí rozhraní příkazového řádku Azure, podívejte se na vlastnost geoReplicationStats. lastSyncTime účtu úložiště.To get the last sync time for the storage account by using Azure CLI, check the storage account's geoReplicationStats.lastSyncTime property. Použijte parametr pro návrat hodnoty vlastností vnořených do geoReplicationStats. --expandUse the --expand parameter to return values for the properties nested under geoReplicationStats. Nezapomeňte nahradit hodnoty zástupných symbolů vlastními hodnotami: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)

TestováníTesting

Je důležité, abyste otestovali, že se vaše aplikace chová podle očekávání, když nalezne chyby s opakováním.It's important to test that your application behaves as expected when it encounters retryable errors. Například je třeba otestovat, že se aplikace přepne do sekundárního a do režimu jen pro čtení, když zjistí problém, a přepne zpět, jakmile bude primární region opět k dispozici.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. K tomu potřebujete způsob, jak simulovat opakované chyby a určit, jak často k nim dochází.To do this, you need a way to simulate retryable errors and control how often they occur.

Pomocí Fiddler můžete zachytit a upravit odpovědi HTTP ve skriptu.You can use Fiddler to intercept and modify HTTP responses in a script. Tento skript může identifikovat odpovědi, které pocházejí z primárního koncového bodu, a změnit stavový kód HTTP na ten, který Klientská knihovna pro úložiště rozpozná jako opakovanou chybu.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. Tento fragment kódu ukazuje jednoduchý příklad skriptu Fiddler, který zachycuje odpovědi na požadavky na čtení v tabulce EmployeeData , aby vrátil stav 502: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;
    }
}

Tento příklad můžete rozšířit tak, aby zachytil širší rozsah požadavků a ResponseCode jenom na některých z nich, aby lépe simuloval scénář reálného světa.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. Další informace o přizpůsobení skriptů Fiddler najdete v tématu Úprava žádosti nebo odpovědi v dokumentaci k Fiddler.For more information about customizing Fiddler scripts, see Modifying a Request or Response in the Fiddler documentation.

Pokud jste provedli prahové hodnoty pro přepínání aplikace na režim jen pro čtení, bude snazší otestovat chování pomocí svazků neprodukčních transakcí.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.

Další krokyNext Steps