Tipy pro zvýšení výkonu pro službu Azure Cosmos DB a sadu .NET SDK v2

PLATÍ PRO: NoSQL

Azure Cosmos DB je rychlá a flexibilní distribuovaná databáze, která se bezproblémově škáluje s garantovanou latencí a propustností. Nemusíte provádět významné změny architektury ani psát složitý kód pro škálování databáze pomocí služby Azure Cosmos DB. Vertikální navýšení a snížení kapacity je stejně snadné jako vytvoření jediného volání rozhraní API. Další informace najdete v tématu zřízení propustnosti kontejneru nebo zřízení propustnosti databáze. Protože je ale služba Azure Cosmos DB přístupná prostřednictvím síťových volání, existují optimalizace na straně klienta, které můžete dosáhnout maximálního výkonu při použití sady SQL .NET SDK.

Pokud se tedy pokoušíte zlepšit výkon databáze, zvažte tyto možnosti:

Upgrade na sadu .NET SDK V3

Sada .NET v3 SDK je vydána. Pokud používáte sadu .NET v3 SDK, projděte si průvodce výkonem .NET v3 s následujícími informacemi:

  • Výchozí nastavení režimu Direct TCP
  • Podpora rozhraní API služby Stream
  • Podpora vlastního serializátoru pro povolení System.Text.JSON využití
  • Integrovaná dávka a hromadná podpora

Doporučení pro hostování

Zapnutí uvolňování paměti na straně serveru (GC)

Snížení frekvence uvolňování paměti může v některých případech pomoct. V .NET nastavte gcServer na true.

Horizontální navýšení kapacity klientské úlohy

Pokud testujete na vysokých úrovních propustnosti (více než 50 000 RU/s), může se klientská aplikace stát kritickým bodem kvůli omezování využití procesoru nebo sítě. Pokud se k tomuto bodu dostanete, můžete účet služby Azure Cosmos DB dál nabízet horizontálním navýšením kapacity klientských aplikací na více serverů.

Poznámka:

Vysoké využití procesoru může způsobit zvýšenou latenci a výjimky časového limitu požadavků.

Operace s metadaty

Neověřujte, že databáze nebo kolekce existuje voláním Create...IfNotExistsAsync nebo v Read...Async horké cestě nebo před provedením operace položky. Ověření by se mělo provést pouze při spuštění aplikace, pokud očekáváte, že se odstraní (jinak není potřeba). Tyto operace metadat generují dodatečnou komplexní latenci, nemají žádnou smlouvu SLA a vlastní samostatná omezení , která se nedají škálovat, jako jsou operace s daty.

Protokolování a trasování

Některá prostředí mají povolenou technologii .NET DefaultTraceListener . DefaultTraceListener představuje problémy s výkonem v produkčních prostředích, což způsobuje vysoké kritické body procesoru a vstupně-výstupních operací. Zkontrolujte a ujistěte se, že je pro vaši aplikaci zakázáno DefaultTraceListener tím, že ji odeberete z TraceListeners v produkčních prostředích .

Nejnovější verze sady SDK (větší než 2.16.2) ji automaticky odeberou, když ji zjistí, ve starších verzích ji můžete odebrat:

if (!Debugger.IsAttached)
{
    Type defaultTrace = Type.GetType("Microsoft.Azure.Documents.DefaultTrace,Microsoft.Azure.DocumentDB.Core");
    TraceSource traceSource = (TraceSource)defaultTrace.GetProperty("TraceSource").GetValue(null);
    traceSource.Listeners.Remove("Default");
    // Add your own trace listeners
}

Sítě

zásady Připojení: Použití režimu přímého připojení

Výchozí režim připojení sady .NET SDK V2 je brána. Režim připojení nakonfigurujete během vytváření DocumentClient instance pomocí parametru ConnectionPolicy . Pokud používáte přímý režim, musíte také nastavit Protocol pomocí parametru ConnectionPolicy . Další informace o různých možnostech připojení najdete v článku o režimech připojení.

Uri serviceEndpoint = new Uri("https://contoso.documents.net");
string authKey = "your authKey from the Azure portal";
DocumentClient client = new DocumentClient(serviceEndpoint, authKey,
new ConnectionPolicy
{
   ConnectionMode = ConnectionMode.Direct, // ConnectionMode.Gateway is the default
   ConnectionProtocol = Protocol.Tcp
});

Vyčerpání dočasných portů

Pokud se ve vašich instancích zobrazí vysoké využití svazku připojení nebo vysokého využití portů, nejprve ověřte, že jsou instance klienta singletony. Jinými slovy, instance klienta by měly být jedinečné po celou dobu života aplikace.

Při spuštění protokolu TCP klient optimalizuje latenci pomocí dlouhotrvajících připojení na rozdíl od protokolu HTTPS, který ukončí připojení po 2 minutách nečinnosti.

Ve scénářích, kdy máte řídký přístup a pokud si v porovnání s přístupem v režimu brány všimnete vyššího počtu připojení, můžete:

Volání openAsync, aby se zabránilo latenci spouštění při prvním požadavku

Ve výchozím nastavení má první požadavek vyšší latenci, protože potřebuje načíst směrovací tabulku adres. Při použití sady SDK V2 zavolejte OpenAsync() jednou během inicializace, abyste se vyhnuli této latenci spouštění při prvním požadavku. Volání vypadá takto: await client.OpenAsync();

Poznámka:

OpenAsync vygeneruje požadavky na získání směrovací tabulky adres pro všechny kontejnery v účtu. Pro účty, které mají mnoho kontejnerů, ale jejichž aplikace přistupuje k podmnožině z nich, OpenAsync by vygenerovalo nepotřebné množství provozu, což by zpomalovalo inicializaci. OpenAsync Použití proto nemusí být v tomto scénáři užitečné, protože zpomaluje spouštění aplikace.

Z hlediska výkonu shromáždíte klienty ve stejné oblasti Azure.

Pokud je to možné, umístěte všechny aplikace, které volají službu Azure Cosmos DB, do stejné oblasti jako databáze Azure Cosmos DB. Tady je přibližné porovnání: Volání služby Azure Cosmos DB ve stejné oblasti se dokončí do 1 ms až 2 ms, ale latence mezi pobřežím USA – západ a východ je větší než 50 ms. Tato latence se může lišit od požadavku na požadavek v závislosti na trase, kterou žádost přijala při průchodu z klienta do hranice datacentra Azure. Nejnižší možnou latenci získáte tím, že se volající aplikace nachází ve stejné oblasti Azure jako zřízený koncový bod služby Azure Cosmos DB. Seznam dostupných oblastí najdete v tématu Oblasti Azure.

Zásady připojení ke službě Azure Cosmos DB

Zvýšení počtu vláken nebo úloh

Vzhledem k tomu, že se volání služby Azure Cosmos DB provádí přes síť, možná budete muset měnit stupeň paralelismu vašich požadavků, aby klientská aplikace strávila minimální dobu čekáním mezi požadavky. Pokud například používáte paralelní knihovnu úloh .NET, vytvořte pořadí stovek úloh, které čtou nebo zapisují do služby Azure Cosmos DB.

Povolení akcelerovaných síťových služeb

Pokud chcete snížit latenci a zpoždění procesoru, doporučujeme povolit akcelerované síťové služby na klientských virtuálních počítačích. Viz Vytvoření virtuálního počítače s Windows s akcelerovanými síťovými službami nebo Vytvoření virtuálního počítače s Linuxem s akcelerovanými síťovými službami.

Využití sady SDK

Instalace nejnovější sady SDK

Sady SDK služby Azure Cosmos DB se neustále vylepšují, aby poskytovaly nejlepší výkon. Informace o nejnovějších vylepšeních sady SDK a kontrole najdete na stránkách sady SDK služby Azure Cosmos DB.

Použití jednoúčelového klienta Azure Cosmos DB po celou dobu životnosti vaší aplikace

Každá DocumentClient instance je bezpečná pro přístup z více vláken a provádí efektivní správu připojení a ukládání adres do mezipaměti při provozu v přímém režimu. Pokud chcete umožnit efektivní správu připojení a lepší výkon klienta sady SDK, doporučujeme po celou dobu životnosti aplikace použít jednu instanci AppDomain .

Vyhněte se blokování volání

Sada SDK služby Azure Cosmos DB by měla být navržená tak, aby zpracovávala mnoho požadavků současně. Asynchronní rozhraní API umožňují malému fondu vláken zpracovávat tisíce souběžných požadavků tím, že nečeká na blokující volání. Místo čekání na dokončení dlouhotrvající synchronní úlohy může vlákno fungovat na jiném požadavku.

Běžný problém s výkonem v aplikacích používajících sadu SDK služby Azure Cosmos DB blokuje volání, která by mohla být asynchronní. Mnoho synchronních blokujících volání vede k hladovění fondu vláken a snížení doby odezvy.

Nepoužívejte:

  • Zablokujte asynchronní provádění voláním Task.Wait nebo Task.Result.
  • Použití Task.Run k vytvoření synchronního rozhraní API asynchronní.
  • Získejte zámky v běžných cestách kódu. Sada .NET SDK služby Azure Cosmos DB je nejvýkonnější při paralelním spouštění kódu.
  • Zavolejte Task.Run a okamžitě ho čekáte. ASP.NET Core už spouští kód aplikace na normálních vláknech fondu vláken, takže volání task.Run vede pouze k nadbytečné plánování fondu vláken. I když by naplánovaný kód blokoval vlákno, Task.Run to nezabrání.
  • Použijte toList(), u DocumentClient.CreateDocumentQuery(...) kterého se používají blokující volání k synchronnímu vyprázdnění dotazu. Pomocí AsDocumentQuery() vyprázdněte dotaz asynchronně.

Udělejte toto:

  • Asynchronní volání rozhraní .NET API služby Azure Cosmos DB
  • Celý zásobník volání je asynchronní, aby bylo možné využívat vzory async/await .

Profiler, například PerfView, lze použít k vyhledání vláken často přidávaných do fondu vláken. Událost Microsoft-Windows-DotNETRuntime/ThreadPoolWorkerThread/Start označuje vlákno přidané do fondu vláken.

Zvýšení System.Net maximálního počtu Připojení ionů na hostitele při použití režimu brány

Požadavky služby Azure Cosmos DB se provádějí přes PROTOKOL HTTPS/REST při použití režimu brány. Podléhají výchozímu limitu připojení na název hostitele nebo IP adresu. Možná budete muset nastavit MaxConnections vyšší hodnotu (100 až 1 000), aby klientská knihovna mohla používat více souběžných připojení ke službě Azure Cosmos DB. V sadě .NET SDK 1.8.0 a novějších je výchozí hodnota pro ServicePointManager.Default Připojení ionLimit 50. Pokud chcete změnit hodnotu, můžete nastavit Documents.Client.PřipojeníionPolicy.Max Připojení ionLimit na vyšší hodnotu.

Implementace backoffu v intervalech RetryAfter

Během testování výkonu byste měli zvýšit zatížení, dokud nedojde k omezení malé míry požadavků. Pokud dojde k omezení požadavků, měla by se klientská aplikace v intervalu opakování zadaného serveru zase vypnout. Dodržování backoffu zajišťuje, že strávíte minimální dobu čekáním mezi opakovanými pokusy.

Podpora zásad opakování je součástí těchto sad SDK:

Další informace naleznete v tématu OpakovatAfter.

V sadě .NET SDK verze 1.19 a novější existuje mechanismus protokolování dalších diagnostických informací a řešení potíží s latencí, jak je znázorněno v následující ukázce. Diagnostický řetězec můžete protokolovat pro požadavky s vyšší latencí čtení. Zachycený diagnostický řetězec vám pomůže pochopit, kolikrát jste u daného požadavku obdrželi chyby 429.

ResourceResponse<Document> readDocument = await this.readClient.ReadDocumentAsync(oldDocuments[i].SelfLink);
readDocument.RequestDiagnosticsString 

Identifikátory URI dokumentů mezipaměti pro nižší latenci čtení

Identifikátory URI dokumentů můžete ukládat do mezipaměti, kdykoli je to možné pro nejlepší výkon čtení. Při vytváření prostředku je potřeba definovat logiku pro ukládání ID prostředku do mezipaměti. Vyhledávání založená na ID prostředků jsou rychlejší než vyhledávání založená na názvu, takže ukládání těchto hodnot do mezipaměti zvyšuje výkon.

Zvýšení počtu vláken nebo úloh

Další informace najdete v části Zvýšení počtu vláken a úloh v části Sítě tohoto článku.

Operace dotazů

Operace dotazů najdete v tipech k výkonu dotazů.

Zásady indexování

Vyloučení nepoužívaných cest z indexování za účelem zrychlení zápisu

Zásady indexování služby Azure Cosmos DB také umožňují určit, které cesty k dokumentu se mají zahrnout nebo vyloučit z indexování pomocí cest indexování (IndexingPolicy.IncludedPaths a IndexingPolicy.ExcludedPaths). Cesty indexování můžou zlepšit výkon zápisu a snížit úložiště indexů pro scénáře, ve kterých jsou vzory dotazů známé předem. Důvodem je to, že náklady indexování korelují přímo s počtem indexovaných jedinečných cest. Tento kód například ukazuje, jak vyloučit celý oddíl dokumentů (podstrom) z indexování pomocí zástupného znaku *:

var collection = new DocumentCollection { Id = "excludedPathCollection" };
collection.IndexingPolicy.IncludedPaths.Add(new IncludedPath { Path = "/*" });
collection.IndexingPolicy.ExcludedPaths.Add(new ExcludedPath { Path = "/nonIndexedContent/*");
collection = await client.CreateDocumentCollectionAsync(UriFactory.CreateDatabaseUri("db"), collection);

Další informace najdete v tématu Zásady indexování služby Azure Cosmos DB.

Propustnost

Měření a ladění pro nižší využití jednotek žádostí za sekundu

Azure Cosmos DB nabízí bohatou sadu databázových operací. Mezi tyto operace patří relační a hierarchické dotazy s funkcemi definovanými uživatelem, uloženými procedurami a triggery, všechny operace s dokumenty v rámci kolekce databází. Náklady spojené s každou z těchto operací se liší v závislosti na procesoru, V/V a paměti potřebné k dokončení operace. Místo posuzování a správy hardwarových prostředků můžete jako jedno opatření pro prostředky požadované k provádění různých databázových operací a požadavku na službu pro aplikaci použít jednotku požadavku (RU).

Propustnost se zřizuje na základě počtu jednotek žádostí nastavených pro každý kontejner. Spotřeba jednotek žádosti se vyhodnocuje jako sazba za sekundu. Aplikace, které překročí zřízenou sazbu jednotek žádosti pro svůj kontejner, jsou omezené, dokud se rychlost nepřesáhne pod zřízenou úroveň kontejneru. Pokud vaše aplikace vyžaduje vyšší úroveň propustnosti, můžete zvýšit propustnost zřízením dalších jednotek žádostí.

Složitost dotazů ovlivňuje, kolik jednotek žádostí se pro operace spotřebuje. Počet predikátů, povaha predikátů, počet definovaných uživatelem a velikost zdrojové datové sady ovlivňují náklady na operace dotazů.

Pokud chcete změřit režii jakékoli operace (vytvoření, aktualizace nebo odstranění), zkontrolujte hlavičku x-ms-request-charge (nebo ekvivalentní RequestCharge vlastnost v FeedResponse\<T>ResourceResponse\<T> sadě .NET SDK) a změřte počet jednotek žádostí spotřebovaných operacemi:

// Measure the performance (Request Units) of writes
ResourceResponse<Document> response = await client.CreateDocumentAsync(collectionSelfLink, myDocument);
Console.WriteLine("Insert of document consumed {0} request units", response.RequestCharge);
// Measure the performance (Request Units) of queries
IDocumentQuery<dynamic> queryable = client.CreateDocumentQuery(collectionSelfLink, queryString).AsDocumentQuery();
while (queryable.HasMoreResults)
    {
        FeedResponse<dynamic> queryResponse = await queryable.ExecuteNextAsync<dynamic>();
        Console.WriteLine("Query batch consumed {0} request units", queryResponse.RequestCharge);
    }

Poplatek za požadavek vrácený v této hlavičce je zlomek zřízené propustnosti (to znamená 2 000 RU za sekundu). Pokud například předchozí dotaz vrátí 1 000 1kB dokumentů, náklady na operaci jsou 1 000. Takže během jedné sekundy server dodržuje pouze dva takové požadavky před omezováním rychlosti pozdějších požadavků. Další informace najdete v tématu Jednotky žádostí a kalkulačka jednotek žádosti.

Zpracování omezování rychlosti nebo příliš velké frekvence požadavků

Když se klient pokusí překročit rezervovanou propustnost pro účet, nedojde na serveru ke snížení výkonu a k žádnému použití kapacity propustnosti nad rezervovanou úroveň. Server předem ukončí požadavek na RequestRateTooLarge (stavový kód HTTP 429). Vrátí hlavičku x-ms-retry-after-ms , která udává dobu v milisekundách, že uživatel musí počkat, než se o požadavek pokusí znovu.

HTTP Status 429,
Status Line: RequestRateTooLarge
x-ms-retry-after-ms :100

Sady SDK všechny implicitně zachytí tuto odpověď, respektují hlavičku opakování zadanou serverem a opakují požadavek. Pokud k vašemu účtu současně přistupuje více klientů, bude další opakování úspěšné.

Pokud máte více než jeden klient, který konzistentně pracuje nad rychlostí požadavků, nemusí být výchozí počet opakování aktuálně nastavený na 9 interně klientem. V tomto případě klient vyvolá do aplikace výjimku DocumentClientException se stavovým kódem 429.

Výchozí počet opakování můžete změnit nastavením instance RetryOptionsConnectionPolicy . Ve výchozím nastavení se výjimka DocumentClientException se stavovým kódem 429 vrátí po kumulativní době čekání 30 sekund, pokud požadavek nadále funguje nad rychlostí požadavků. Tato chyba se vrátí i v případě, že je aktuální počet opakování menší než maximální počet opakování, ať už je aktuální hodnota výchozí hodnotou 9 nebo uživatelem definovaná hodnota.

Automatizované chování opakování pomáhá zlepšit odolnost a použitelnost většiny aplikací. Nemusí se ale jednat o nejlepší chování při srovnávacích testech výkonu, zejména při měření latence. Latence pozorovaná klientem se zvýší, pokud experiment dosáhne omezení serveru a způsobí tiché opakování klientské sady SDK. Abyste se vyhnuli špičkám latence během experimentů s výkonem, změřte poplatky vrácené jednotlivými operacemi a zajistěte, aby požadavky fungovaly pod rezervovanou rychlostí požadavků. Další informace najdete v tématu Jednotky žádostí.

Pro zajištění vyšší propustnosti navrhujte menší dokumenty.

Poplatek za požadavek (tj. náklady na zpracování požadavku) dané operace koreluje přímo s velikostí dokumentu. Operace s velkými dokumenty stojí více než operace s malými dokumenty.

Další kroky

Ukázkovou aplikaci, která se používá k vyhodnocení služby Azure Cosmos DB pro vysoce výkonné scénáře na několika klientských počítačích, najdete v tématu Testování výkonu a škálování pomocí služby Azure Cosmos DB.

Další informace o návrhu aplikace pro škálování a vysoký výkon najdete v tématu Dělení a škálování ve službě Azure Cosmos DB.