Tipy pro zvýšení výkonu pro sadu Java SDK v4 služby Azure Cosmos DB

PLATÍ PRO: NoSQL

Důležité

Tipy k výkonu v tomto článku jsou určené jenom pro sadu Java SDK služby Azure Cosmos DB verze 4. Další informace najdete v průvodci odstraňováním potíží se sadou Azure Cosmos DB Java SDK verze 4, úložištěm Maven a sadou Java SDK služby Azure Cosmos DB verze 4. Pokud aktuálně používáte starší verzi než v4, přečtěte si průvodce migrací na sadu Java SDK služby Azure Cosmos DB verze 4 , kde najdete pomoc s upgradem na verzi 4.

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 nebo volání metody sady SDK. Vzhledem k tomu, že je služba Azure Cosmos DB přístupná prostřednictvím síťových volání, existují optimalizace na straně klienta, které můžete provést, abyste dosáhli maximálního výkonu při použití sady Azure Cosmos DB Java SDK v4.

Pokud se tedy ptáte, jak můžu zlepšit výkon databáze? zvažte následující možnosti:

Sítě

  • Sloučit klienty ve stejné oblasti Azure pro zajištění výkonu

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. Pro přibližné porovnání se volání služby Azure Cosmos DB ve stejné oblasti dokončí do 1 až 2 ms, ale latence mezi pobřežím USA – západ a východ je >50 ms. Tato latence se může pravděpodobně lišit od požadavku na požadavek v závislosti na trase, kterou žádost vzala při průchodu z klienta do hranice datacentra Azure. Nejnižší možné latence se dosahuje 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.

Obrázek zásad připojení ke službě Azure Cosmos DB

Aplikace, která komunikuje s účtem Azure Cosmos DB ve více oblastech, musí nakonfigurovat upřednostňovaná umístění , aby se zajistilo, že požadavky přejdou do kompletované oblasti.

Povolení akcelerovaných síťových služeb za účelem snížení latence a zpoždění procesoru

Důrazně doporučujeme postupovat podle pokynů, abyste ve Windows povolili akcelerované síťové služby (vyberte pokyny) nebo Linux (vyberte pokyny), aby se virtuální počítač Azure maximalizoval tím, že sníží latenci a zpoždění procesoru.

Bez akcelerovaných síťových operací se vstupně-výstupní operace mezi vaším virtuálním počítačem Azure a dalšími prostředky Azure můžou směrovat 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. Díky akcelerovaným síťovým rozhraním se virtuální počítače přímo se síťovým rozhraním bez zprostředkovatelů. Všechny podrobnosti o zásadách sítě se zpracovávají v hardwaru síťové karty a obcházejí hostitele a virtuální přepínač. 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ší informace najdete v pokynech pro Windows a Linux .

Ladění konfigurace přímého připojení a připojení brány

Informace o optimalizaci konfigurací připojení v režimu přímé a brány najdete v tématu ladění konfigurací připojení pro sadu Java SDK v4.

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. Pokud chcete zjistit nejnovější vylepšení sady SDK, navštivte sadu SDK služby Azure Cosmos DB.

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

Každá instance klienta Azure Cosmos DB 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. Pokud chcete klientům Služby Azure Cosmos DB umožnit efektivní správu připojení a vyšší výkon, důrazně doporučujeme po celou dobu životnosti aplikace používat jednu instanci klienta Služby Azure Cosmos DB.

  • Použití nejnižší úrovně konzistence vyžadované pro vaši aplikaci

Když vytvoříte CosmosClient, použije se výchozí konzistence, pokud není explicitně nastavená, relace. Pokud logika aplikace nevyžaduje konzistenci relace , nastavte konzistenci na Konečnou. Poznámka: Doporučuje se používat alespoň konzistenci relace v aplikacích, které využívají procesor kanálu změn služby Azure Cosmos DB.

  • Použití asynchronního rozhraní API k dosažení maximální zřízené propustnosti

Sada Azure Cosmos DB Java SDK v4 má dvě rozhraní API, synchronní a asynchronní. Zhruba řečeno, asynchronní rozhraní API implementuje funkce sady SDK, zatímco synchronizační rozhraní API je tenký obálka, která blokuje volání asynchronního rozhraní API. To je na rozdíl od starší sady Azure Cosmos DB Async Java SDK verze 2, která byla pouze asynchronní a starší sada Java SDK služby Azure Cosmos DB v2, která byla pouze synchronizace a měla samostatnou implementaci.

Volba rozhraní API je určena během inicializace klienta; CosmosAsyncClient podporuje asynchronní rozhraní API, zatímco CosmosClient podporuje synchronizační rozhraní API.

Asynchronní rozhraní API implementuje neblokující vstupně-výstupní operace a je optimální volbou v případě, že vaším cílem je dosáhnout maximální propustnosti při vydávání požadavků do služby Azure Cosmos DB.

Použití synchronizačního rozhraní API může být správnou volbou, pokud chcete nebo potřebujete rozhraní API, které blokuje odpověď na jednotlivé požadavky nebo pokud je synchronní operace dominantním paradigmatem vaší aplikace. Například můžete chtít rozhraní API pro synchronizaci při zachování dat do služby Azure Cosmos DB v aplikaci mikroslužeb za předpokladu, že propustnost není kritická.

Všimněte si snížení propustnosti rozhraní API synchronizace s rostoucí dobou odezvy požadavků, zatímco asynchronní rozhraní API může saturovat možnosti plné šířky pásma vašeho hardwaru.

Geografická kolkace vám může poskytnout vyšší a konzistentnější propustnost při použití rozhraní SYNC API (viz Kolacete klienty ve stejné oblasti Azure kvůli výkonu), ale stále se neočekává, že by překročila dosažitelnou propustnost asynchronního rozhraní API.

Někteří uživatelé můžou být také neznámí v projektu Reactor, reaktivní Toky architektura použitá k implementaci asynchronního rozhraní JAVA SDK služby Azure Cosmos DB v4. Pokud se jedná o problém, doporučujeme přečíst si úvodní průvodce vzorem reactor a pak se podívat na tento úvod k reaktivnímu programování , abyste se seznámili. Pokud jste už službu Azure Cosmos DB používali s asynchronním rozhraním a sadou SDK, kterou jste použili, byla sada Azure Cosmos DB Async Java SDK v2, možná znáte ReactiveX/RxJava, ale nejste si jistí, co se změnilo v projektu Reactor. V takovém případě se podívejte na naši příručku Reactor vs. RxJava, abyste se seznámili.

Následující fragmenty kódu ukazují, jak inicializovat klienta Služby Cosmos DB pro asynchronní rozhraní API nebo operaci synchronizačního rozhraní API:

Rozhraní Async API sady Java SDK V4 (Maven com::azure-cosmos)


CosmosAsyncClient client = new CosmosClientBuilder()
        .endpoint(HOSTNAME)
        .key(MASTERKEY)
        .consistencyLevel(CONSISTENCY)
        .buildAsyncClient();

  • Škálování úlohy klienta na více instancí

Pokud testujete na vysokých úrovních propustnosti, 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ů.

Dobrým pravidlem je nepřesáhlo >50% využití procesoru na jakémkoli daném serveru, aby byla latence nízká.

  • Použití vhodného plánovače (vyhněte se krádeži vláken IO Netty smyčky událostí)

Asynchronní funkce sady Azure Cosmos DB Java SDK je založená na neblokujících vstupně-výstupních operacích netty . Sada SDK používá pro provádění vstupně-výstupních operací pevný počet vláken smyčky Netty vstupně-výstupních operací (počet procesorových jader vašeho počítače). Tok vrácený rozhraním API vygeneruje výsledek na jednom ze sdílených vláken Netty smyčky událostí vstupně-výstupních událostí. Proto je důležité neblokovat sdílená vlákna Netty smyčky událostí vstupně-výstupních operací. Operace náročné na procesor nebo blokování ve vlákně netty smyčky událostí vstupně-výstupních operací může způsobit zablokování nebo výrazně snížit propustnost sady SDK.

Například následující kód provede práci náročnou na procesor na vlákně io netty smyčky událostí:


Mono<CosmosItemResponse<CustomPOJO>> createItemPub = asyncContainer.createItem(item);
createItemPub.subscribe(
        itemResponse -> {
            //this is executed on eventloop IO netty thread.
            //the eventloop thread is shared and is meant to return back quickly.
            //
            // DON'T do this on eventloop IO netty thread.
            veryCpuIntensiveWork();
        });


Po přijetí výsledku byste se měli vyhnout jakékoli práci náročné na procesoru na výsledku ve vlákně io netty smyčky událostí. Místo toho můžete zadat vlastní plánovač, který vám poskytne vlastní vlákno pro spuštění práce, jak je znázorněno níže (vyžaduje import reactor.core.scheduler.Schedulers).


Mono<CosmosItemResponse<CustomPOJO>> createItemPub = asyncContainer.createItem(item);
createItemPub
        .publishOn(Schedulers.parallel())
        .subscribe(
                itemResponse -> {
                    //this is now executed on reactor scheduler's parallel thread.
                    //reactor scheduler's parallel thread is meant for CPU intensive work.
                    veryCpuIntensiveWork();
                });

Na základě typu práce byste měli pro svou práci použít odpovídající existující plánovač reactor. Přečtěte si zde Schedulers.

Pokud chcete lépe porozumět modelu vláken a plánování projektu Reactor, přečtěte si tento blogový příspěvek od Project Reactor.

Další informace o sadě Azure Cosmos DB Java SDK v4 najdete v adresáři Azure Cosmos DB monorepo sady Azure SDK pro Javu na GitHubu.

  • Optimalizace nastavení protokolování v aplikaci

Z různýchdůvodůch Pokud vaším cílem je plně saturovat zřízenou propustnost kontejneru požadavky vygenerovanými tímto vláknem, optimalizace protokolování můžou výrazně zlepšit výkon.

  • Konfigurace asynchronního protokolovacího nástroje

Latence synchronního protokolovacího nástroje nutně ovlivňuje celkový výpočet latence vlákna generujícího požadavek. Asynchronní protokolovací nástroj, jako je log4j2 , se doporučuje oddělit režijní náklady na protokolování od vysoce výkonných vláken aplikace.

  • Zakázání protokolování netty

Protokolování knihovny Netty je chatty a je potřeba ho vypnout (potlačení přihlášení nemusí stačit), aby se zabránilo dalším nákladům na procesor. Pokud nejste v režimu ladění, zakažte protokolování netty úplně. Pokud tedy používáte Log4j k odebrání dalších nákladů na procesor, které org.apache.log4j.Category.callAppenders() vzniknou z netty, přidejte do základu kódu následující řádek:

org.apache.log4j.Logger.getLogger("io.netty").setLevel(org.apache.log4j.Level.OFF);
  • Limit prostředků o otevření souborů operačního systému

Některé systémy Linux (například Red Hat) mají horní limit počtu otevřených souborů, takže celkový počet připojení. Spuštěním následujícího příkazu zobrazte aktuální limity:

ulimit -a

Počet otevřených souborů (nofile) musí být dostatečně velký, aby měl dostatek místa pro nakonfigurovanou velikost fondu připojení a další otevřené soubory operačního systému. Dá se upravit tak, aby umožňoval větší velikost fondu připojení.

Otevřete soubor limits.conf:

vim /etc/security/limits.conf

Přidejte nebo upravte následující řádky:

* - nofile 100000
  • Zadání klíče oddílu v zápisech bodů

Pokud chcete zvýšit výkon zápisů bodů, zadejte klíč oddílu položky ve volání rozhraní API pro zápis bodu, jak je znázorněno níže:

Rozhraní Async API sady Java SDK V4 (Maven com::azure-cosmos)

asyncContainer.createItem(item,new PartitionKey(pk),new CosmosItemRequestOptions()).block();

Místo poskytnutí pouze instance položky, jak je znázorněno níže:

Rozhraní Async API sady Java SDK V4 (Maven com::azure-cosmos)

asyncContainer.createItem(item).block();

Druhá možnost je podporovaná, ale do vaší aplikace přidá latenci; Sada SDK musí analyzovat položku a extrahovat klíč oddílu.

Operace dotazů

Informace o operacích 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 umožňují určit, které cesty k dokumentu se mají zahrnout nebo vyloučit z indexování pomocí cest indexování (setIncludedPaths a setExcludedPaths). Použití cest indexování může nabídnout lepší výkon zápisu a nižší úložiště indexů pro scénáře, ve kterých jsou vzory dotazů známé předem, protože náklady na indexování přímo korelují s počtem indexovaných jedinečných cest. Následující kód například ukazuje, jak zahrnout a vyloučit celé části dokumentů (označované také jako podstrom) z indexování pomocí zástupného znaku "*".


CosmosContainerProperties containerProperties = new CosmosContainerProperties(containerName, "/lastName");

// Custom indexing policy
IndexingPolicy indexingPolicy = new IndexingPolicy();
indexingPolicy.setIndexingMode(IndexingMode.CONSISTENT);

// Included paths
List<IncludedPath> includedPaths = new ArrayList<>();
includedPaths.add(new IncludedPath("/*"));
indexingPolicy.setIncludedPaths(includedPaths);

// Excluded paths
List<ExcludedPath> excludedPaths = new ArrayList<>();
excludedPaths.add(new ExcludedPath("/name/*"));
indexingPolicy.setExcludedPaths(excludedPaths);

containerProperties.setIndexingPolicy(indexingPolicy);

ThroughputProperties throughputProperties = ThroughputProperties.createManualThroughput(400);

database.createContainerIfNotExists(containerProperties, throughputProperties);
CosmosAsyncContainer containerIfNotExists = database.getContainer(containerName);

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

Propustnost

  • Měření a ladění nižších jednotek žádostí za sekundu

Azure Cosmos DB nabízí bohatou sadu databázových operací, včetně relačních a hierarchických dotazů s funkcemi definované uživatelem, uloženými procedurami a triggery – všechny operace s dokumenty v rámci kolekce databází. Náklady spojené s jednotlivými operacemi 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ů, si můžete představit jednotku žádostí (RU) jako jednu míru pro prostředky potřebné k provádění různých databázových operací a žá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 sazba za sekundu. Aplikace, které překročí zřízenou jednotkovou sazbu požadavku pro svůj kontejner, jsou omezené, dokud se rychlost sníží 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 dotazu má vliv na počet jednotek žádostí spotřebovaných pro operaci. Počet predikátů, povaha predikátů, počet definovaných uživatelem a velikost sady zdrojových dat ovlivňují náklady na operace dotazu.

Pokud chcete změřit režii jakékoli operace (vytvoření, aktualizace nebo odstranění), zkontrolujte hlavičku x-ms-request-charge a změřte počet jednotek žádostí spotřebovaných těmito operacemi. Můžete se také podívat na ekvivalentní RequestCharge vlastnost ResourceResponse<T> nebo FeedResponse<T>.

Rozhraní Async API sady Java SDK V4 (Maven com::azure-cosmos)

CosmosItemResponse<CustomPOJO> response = asyncContainer.createItem(item).block();

response.getRequestCharge();

Poplatek za požadavek vrácený v této hlavičce je zlomkem zřízené propustnosti. Pokud máte například zřízeno 2000 RU/s a pokud předchozí dotaz vrátí 1 000 1kB dokumentů, náklady na operaci jsou 1 000. V rámci jedné sekundy server respektuje pouze dva takové požadavky před omezováním rychlosti následný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 využití kapacity propustnosti nad rámec rezervované úrovně. Server předem ukončí požadavek pomocí requestRateTooLarge (stavový kód HTTP 429) a vrátí hlavičku x-ms-retry-after-ms označující dobu v milisekundách, že uživatel musí před opětovným spuštěním požadavku počkat.

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á výjimku CosmosClientException se stavovým kódem 429 pro aplikaci. Výchozí počet opakování lze změnit pomocí setMaxRetryAttemptsOnThrottledRequests()ThrottlingRetryOptions instance. Ve výchozím nastavení se výjimka CosmosClientException 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ů. K tomu dochází i v případě, že je aktuální počet opakování menší než maximální počet opakování, jedná se o výchozí hodnotu 9 nebo uživatelem definovanou hodnotu.

I když automatizované chování opakování pomáhá zlepšit odolnost a použitelnost pro většinu aplikací, může při provádění srovnávacích testů výkonu přicházet k pravděpodobnosti, 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í.

  • Návrh menších dokumentů pro vyšší propustnost

Poplatek za žádost (náklady na zpracování požadavku) dané operace přímo koreluje s velikostí dokumentu. Operace s velkými dokumenty stojí více než operace u malých dokumentů. V ideálním případě můžete aplikaci a pracovní postupy navrhovat tak, aby velikost položky byla ~1 kB nebo podobná. U aplikací citlivých na latenci byste se měli vyhnout velkým položkám – dokumenty s více MB zpomalují vaši aplikaci.

Další kroky

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.

Pokoušíte se naplánovat kapacitu migrace do služby Azure Cosmos DB? Informace o stávajícím databázovém clusteru můžete použít k plánování kapacity.