Tipy pro zvýšení výkonu pro Azure Cosmos DB a .NET

PLATÍ PRO: NoSQL

Azure Cosmos DB je rychlá a flexibilní distribuovaná databáze, která se bezproblémově škáluje s garantovanou latencí a úrovněmi propustnosti. 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.

Vzhledem k tomu, že ke službě Azure Cosmos DB se přistupuje přes síťová volání, můžete provést optimalizace na straně klienta, abyste dosáhli maximálního výkonu při použití sady SQL .NET SDK.

Pokud se pokoušíte zlepšit výkon databáze, zvažte možnosti uvedené v následujících částech.

Doporučení pro hostování

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

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 vysoké úrovně propustnosti nebo rychlostí vyšší než 50 000 jednotek žádostí za sekundu (RU/s), může se z klientské aplikace stát kritický bod úlohy. Důvodem je to, že počítač může vyžadovat maximální 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 kontejner existuje voláním Create...IfNotExistsAsyncRead...Async nebo v 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ž 3.23.0) ji automaticky odeberou, když ji zjistí, ve starších verzích ji můžete odebrat:

if (!Debugger.IsAttached)
{
    Type defaultTrace = Type.GetType("Microsoft.Azure.Cosmos.Core.Trace.DefaultTrace,Microsoft.Azure.Cosmos.Direct");
    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 V3 SDK je přímý s protokolem TCP. Režim připojení nakonfigurujete při vytváření CosmosClient instance v CosmosClientOptions. Další informace o různých možnostech připojení najdete v článku o režimech připojení.

string connectionString = "<your-account-connection-string>";
CosmosClient client = new CosmosClient(connectionString,
new CosmosClientOptions
{
    ConnectionMode = ConnectionMode.Gateway // ConnectionMode.Direct is the default
});

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.

Když běží na protokolu TCP, klient optimalizuje latenci pomocí dlouhotrvajících připojení. To je na rozdíl od protokolu HTTPS, který ukončí připojení po dvou minutách nečinnosti.

Ve scénářích, ve kterých 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:

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 milisekund (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 tak, ž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.

Shromážděte klienty ve stejné oblasti.

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

Vzhledem k tomu, že volání do služby Azure Cosmos DB se provádějí přes síť, může být potřeba měnit stupeň souběžnosti 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 za účelem snížení latence a zpoždění procesoru

Pokud chcete maximalizovat výkon, doporučujeme postupovat podle pokynů k povolení akcelerovaných síťových služeb ve Windows (kliknutím zobrazíte pokyny) nebo Linuxu (kliknutím na pokyny).

Bez akcelerovaných síťových operací může být vstupně-výstupní operace mezi vaším virtuálním počítačem Azure a dalšími prostředky Azure zbytečně směrována přes hostitele a virtuální přepínač umístěný mezi virtuálním počítačem a jeho síťovou kartou. Když je hostitel a virtuální přepínač vložený do cesty k datům, nejen zvyšuje latenci a zpoždění v komunikačním kanálu, ale také ukradne cykly procesoru z virtuálního počítače. S akcelerovanými síťovými službami rozhraní virtuálních počítačů přímo se síťovým rozhraním bez zprostředkovatelů; veškeré podrobnosti o zásadách sítě, které byly zpracovány hostitelem a virtuálním přepínačem, se nyní zpracovávají v hardwaru síťové karty; hostitel a virtuální přepínač se vynechá. Obecně můžete očekávat nižší latenci a vyšší propustnost, stejně jako konzistentnější latenci a snížení využití procesoru, když povolíte akcelerované síťové služby.

Omezení: Akcelerované síťové služby musí být podporovány v operačním systému virtuálního počítače a dají se povolit jenom v případě, že je virtuální počítač zastavený a uvolněný. Virtuální počítač nejde nasadit pomocí Azure Resource Manageru. Služba App Service nemá povolenou akcelerovanou síť.

Další podrobnosti najdete v pokynech pro Windows a Linux .

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 zjištění nejnovějších vylepšení sady SDK a kontrole najdete v tématu Sada SDK služby Azure Cosmos DB.

Použití rozhraní API streamu

Sada .NET SDK V3 obsahuje rozhraní API datových proudů, která mohou přijímat a vracet data bez serializace.

Aplikace střední vrstvy, které nespotřebovávají odpovědi přímo ze sady SDK, ale předávají je do jiných aplikačních vrstev, můžou využívat rozhraní API streamu. Příklady zpracování datových proudů najdete v ukázkách správy položek.

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

Každá CosmosClient 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, když funguje v přímém režimu. Pokud chcete umožnit efektivní správu připojení a lepší výkon klienta sady SDK, doporučujeme pro každý účet, se kterým vaše aplikace komunikuje, používat jednu instanci po AppDomain celou dobu životnosti aplikace.

Informace o víceklientských aplikacích, které zpracovávají více účtů, najdete v souvisejících osvědčených postupech.

Když pracujete na Azure Functions, instance by také měly dodržovat stávající pokyny a udržovat jednu instanci.

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í.
  • Nepoužívejte toList(), u Container.GetItemLinqQueryable<T>() kterého se používají blokující volání k synchronnímu vyprázdnění dotazu. Pomocí toFeedIterator() 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.

Zakázání odpovědi na obsah při operacích zápisu

U úloh, které mají velké objemy datových částí, nastavte EnableContentResponseOnWrite možnost požadavku na falsehodnotu . Služba už nebude do sady SDK vracet vytvořený nebo aktualizovaný prostředek. Za normálních okolností, protože aplikace má vytvořený objekt, nepotřebuje službu k vrácení. Hodnoty hlaviček jsou stále přístupné, například poplatky za požadavek. Zakázání odpovědi na obsah může přispět ke zlepšení výkonu, protože sada SDK už nemusí přidělovat paměť nebo serializovat tělo odpovědi. Snižuje také využití šířky pásma sítě, aby se dále pomohl výkon.

ItemRequestOptions requestOptions = new ItemRequestOptions() { EnableContentResponseOnWrite = false };
ItemResponse<Book> itemResponse = await this.container.CreateItemAsync<Book>(book, new PartitionKey(book.pk), requestOptions);
// Resource will be null
itemResponse.Resource

Povolení hromadné optimalizace propustnosti místo latence

Povolte hromadně pro scénáře, ve kterých úloha vyžaduje velkou propustnost a latence není tak důležitá. Další informace o povolení funkce Bulk a informace o tom, pro které scénáře se má použít, najdete v tématu Úvod k hromadné podpoře.

Zvýšení System.Net max 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 (od 100 do 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 hodnotu změnit, můžete ji nastavit Documents.Client.ConnectionPolicy.MaxConnectionLimit na vyšší hodnotu.

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

Viz Zvýšení počtu vláken nebo ú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).

Indexování pouze potřebných cest může zlepšit výkon zápisu, snížit poplatky za RU při operacích 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. Například následující kód ukazuje, jak vyloučit celý oddíl dokumentů (podstrom) z indexování pomocí zástupného znaku "*":

var containerProperties = new ContainerProperties(id: "excludedPathCollection", partitionKeyPath: "/pk" );
containerProperties.IndexingPolicy.IncludedPaths.Add(new IncludedPath { Path = "/*" });
containerProperties.IndexingPolicy.ExcludedPaths.Add(new ExcludedPath { Path = "/nonIndexedContent/*");
Container container = await this.cosmosDatabase.CreateContainerAsync(containerProperties);

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í RU/s

Azure Cosmos DB nabízí bohatou sadu databázových operací. Mezi tyto operace patří relační a hierarchické dotazy se soubory univerzálního disku (UDF), 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, které jsou potřeba k dokončení operace. Místo toho, abyste přemýšleli o hardwarových prostředcích a správě hardwarových prostředků, můžete jednotku žádostí považovat za jedinou míru pro prostředky, které jsou potřeba k provádění různých databázových operací a poskytování žádosti o aplikaci.

Propustnost se zřizuje na základě počtu jednotek žádostí nastavených pro každý kontejner. Spotřeba jednotek žádosti se vyhodnocuje jako míra jednotek 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 souborů UDF 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
ItemResponse<Book> response = await container.CreateItemAsync<Book>(myBook, new PartitionKey(myBook.PkValue));
Console.WriteLine("Insert of item consumed {0} request units", response.RequestCharge);
// Measure the performance (Request Units) of queries
FeedIterator<Book> queryable = container.GetItemQueryIterator<ToDoActivity>(queryString);
while (queryable.HasMoreResults)
    {
        FeedResponse<Book> queryResponse = await queryable.ExecuteNextAsync<Book>();
        Console.WriteLine("Query batch consumed {0} request units", queryResponse.RequestCharge);
    }

Poplatek za požadavek vrácený v této hlavičce je zlomkem zřízené propustnosti (tedy 2 000 RU/s). 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 tím, než omezí rychlost 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 znovu pokusí.

    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í, který je aktuálně nastaven na 9 interně klientem, stačit. V tomto případě klient vyvolá výjimku CosmosException se stavovým kódem 429 pro aplikaci.

Výchozí počet opakování můžete změnit nastavením instance RetryOptionsCosmosClientOptions . Ve výchozím nastavení se výjimka CosmosException 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í hodnota 9 nebo uživatelsky 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) zadané 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.