Sdílet prostřednictvím


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 .

Vysoká dostupnost

Obecné pokyny ke konfiguraci vysoké dostupnosti ve službě Azure Cosmos DB najdete v tématu Vysoká dostupnost ve službě Azure Cosmos DB.

Kromě dobrého základního nastavení v databázové platformě existují specifické techniky, které je možné implementovat v samotné sadě Java SDK, což může pomoct ve scénářích výpadků. Dvě velmi vhodné strategie jsou strategie dostupnosti založená na prahové hodnotě a jistič na úrovni oddílů.

Tyto techniky poskytují pokročilé mechanismy pro řešení konkrétních problémů s latencí a dostupností, které jsou nad rámec možností opakování napříč oblastmi, které jsou ve výchozím nastavení integrované do sady SDK. Díky proaktivní správě potenciálních problémů na úrovni požadavků a oddílů můžou tyto strategie výrazně zvýšit odolnost a výkon vaší aplikace, zejména za vysoce zatížených nebo snížených podmínek.

Strategie dostupnosti založená na prahových hodnotách

Strategie dostupnosti založená na prahových hodnotách může zlepšit latenci a dostupnost tím, že odesílá paralelní žádosti o čtení do sekundárních oblastí a přijímá nejrychlejší odpověď. Tento přístup může výrazně snížit dopad regionálních výpadků nebo podmínek s vysokou latencí na výkon aplikace. Kromě toho je možné proaktivní správu připojení využít k dalšímu zvýšení výkonu tím, že zahřejete připojení a mezipaměti v aktuální oblasti čtení i upřednostňovaných vzdálených oblastech.

Příklad konfigurace:

// Proactive Connection Management
CosmosContainerIdentity containerIdentity = new CosmosContainerIdentity("sample_db_id", "sample_container_id");
int proactiveConnectionRegionsCount = 2;
Duration aggressiveWarmupDuration = Duration.ofSeconds(1);

CosmosAsyncClient clientWithOpenConnections = new CosmosClientBuilder()
          .endpoint("<account URL goes here")
          .key("<account key goes here>")
          .endpointDiscoveryEnabled(true)
          .preferredRegions(Arrays.asList("sample_region_1", "sample_region_2"))
          .openConnectionsAndInitCaches(new CosmosContainerProactiveInitConfigBuilder(Arrays.asList(containerIdentity))
                .setProactiveConnectionRegionsCount(proactiveConnectionRegionsCount)
                 //setting aggressive warmup duration helps in cases where there is a high no. of partitions
                .setAggressiveWarmupDuration(aggressiveWarmupDuration)
                .build())
          .directMode()
          .buildAsyncClient();

CosmosAsyncContainer container = clientWithOpenConnections.getDatabase("sample_db_id").getContainer("sample_container_id");

int threshold = 500;
int thresholdStep = 100;

CosmosEndToEndOperationLatencyPolicyConfig config = new CosmosEndToEndOperationLatencyPolicyConfigBuilder(Duration.ofSeconds(3))
        .availabilityStrategy(new ThresholdBasedAvailabilityStrategy(Duration.ofMillis(threshold), Duration.ofMillis(thresholdStep)))
        .build();

CosmosItemRequestOptions options = new CosmosItemRequestOptions();
options.setCosmosEndToEndOperationLatencyPolicyConfig(config);

container.readItem("id", new PartitionKey("pk"), options, JsonNode.class).block();

// Write operations can benefit from threshold-based availability strategy if opted into non-idempotent write retry policy 
// and the account is configured for multi-region writes.
options.setNonIdempotentWriteRetryPolicy(true, true);
container.createItem("id", new PartitionKey("pk"), options, JsonNode.class).block();

Jak to funguje:

  1. Počáteční požadavek: V době T1 se požadavek na čtení provede v primární oblasti (například USA – východ). Sada SDK čeká na odpověď až na 500 milisekund ( threshold hodnota).

  2. Druhý požadavek: Pokud primární oblast neobsahuje odpověď v rozsahu 500 milisekund, odešle se paralelní požadavek do další upřednostňované oblasti (například USA – východ 2).

  3. Třetí požadavek: Pokud primární ani sekundární oblast nereaguje do 600 milisekund (500 ms + 100 ms), thresholdStep sada SDK odešle další paralelní požadavek do třetí upřednostňované oblasti (například USA – západ).

  4. Nejrychlejší odpověď wins: Která oblast odpoví jako první, tato odpověď se přijme a ostatní paralelní požadavky se ignorují.

Proaktivní správa připojení pomáhá zahříváním připojení a mezipamětí pro kontejnery v upřednostňovaných oblastech, což snižuje latenci studeného spuštění pro scénáře převzetí služeb při selhání nebo zápisy v nastaveních s více oblastmi.

Tato strategie může výrazně zlepšit latenci ve scénářích, kdy je určitá oblast pomalá nebo dočasně nedostupná, ale pokud jsou vyžadovány paralelní požadavky napříč oblastmi, může to vyžadovat vyšší náklady z hlediska jednotek žádostí.

Poznámka:

Pokud první upřednostňovaná oblast vrátí kód stavu ne přechodné chyby (např. dokument nebyl nalezen, chyba autorizace, konflikt atd.), samotná operace selže rychle, protože strategie dostupnosti by v tomto scénáři neměla žádnou výhodu.

Jistič na úrovni oddílů

Jistič na úrovni oddílu vylepšuje koncovou latenci a dostupnost zápisu sledováním a zkratováním požadavků na fyzické oddíly, které nejsou v pořádku. Zlepšuje výkon tím, že se vyhne známým problematickým oddílům a přesměruje požadavky do zdravějších oblastí.

Příklad konfigurace:

Povolení jističe na úrovni oddílu:

System.setProperty(
   "COSMOS.PARTITION_LEVEL_CIRCUIT_BREAKER_CONFIG",
      "{\"isPartitionLevelCircuitBreakerEnabled\": true, "
      + "\"circuitBreakerType\": \"CONSECUTIVE_EXCEPTION_COUNT_BASED\","
      + "\"consecutiveExceptionCountToleratedForReads\": 10,"
      + "\"consecutiveExceptionCountToleratedForWrites\": 5,"
      + "}");

Nastavení frekvence procesu na pozadí pro kontrolu nedostupných oblastí:

System.setProperty("COSMOS.STALE_PARTITION_UNAVAILABILITY_REFRESH_INTERVAL_IN_SECONDS", "60");

Nastavení doby trvání, po kterou může oddíl zůstat nedostupný:

System.setProperty("COSMOS.ALLOWED_PARTITION_UNAVAILABILITY_DURATION_IN_SECONDS", "30");

Jak to funguje:

  1. Sledování selhání: Sada SDK sleduje selhání terminálu (např. 503s, 500s, vypršení časového limitu) pro jednotlivé oddíly v konkrétních oblastech.

  2. Označení jako nedostupné: Pokud oddíl v oblasti překročí nakonfigurovanou prahovou hodnotu selhání, označí se jako nedostupný. Následné požadavky na tento oddíl jsou zkrácené a přesměrované do jiných healthier oblastí.

  3. Automatizované obnovení: Vlákno na pozadí pravidelně kontroluje nedostupné oddíly. Po určité době jsou tyto oddíly nezávazně označeny jako "HealthyTentative" a podléhají testování požadavků na ověření obnovení.

  4. Povýšení nebo snížení úrovně stavu: Na základě úspěchu nebo selhání těchto testovacích požadavků se stav oddílu buď zvýší na hodnotu V pořádku, nebo se opět sníží na Nedostupný.

Tento mechanismus pomáhá nepřetržitě monitorovat stav oddílu a zajišťuje, aby se požadavky obsluhovaly s minimální latencí a maximální dostupností, aniž by došlo k výpadku problematickými oddíly.

Poznámka:

Jistič se vztahuje pouze na účty pro zápis do více oblastí, jako když je oddíl označený jako Unavailable, přesunou se čtení i zápisy do další upřednostňované oblasti. Tím zabráníte tomu, aby se čtení a zápisy z různých oblastí obsluhovaly ze stejné instance klienta, protože by to byl anti-vzor.

Důležité

Abyste mohli aktivovat jistič na úrovni oddílů, musíte používat verzi 4.63.0 sady Java SDK nebo vyšší.

Porovnání optimalizací dostupnosti

  • Strategie dostupnosti založená na prahových hodnotách:

    • Výhoda: Snižuje koncovou latenci odesíláním paralelních žádostí o čtení do sekundárních oblastí a zlepšuje dostupnost tím, že požadavky předprázdní, které budou mít za následek vypršení časového limitu sítě.
    • Kompromis: V porovnání s jističem se účtují další náklady na RU (jednotky žádostí) kvůli dalším paralelním žádostem mezi oblastmi (i když pouze během období, kdy dojde k porušení prahových hodnot).
    • Případ použití: Optimální pro úlohy náročné na čtení, u kterých je kritická latence, a některé další náklady (z hlediska poplatků za RU i zatížení procesoru klienta) jsou přijatelné. Operace zápisu můžou také těžit, pokud se přihlásíte k zásadám opakování zápisu bez idempotentního zápisu a účet má zápisy do více oblastí.
  • Jistič na úrovni oddílů:

    • Výhoda: Vylepšuje dostupnost a latenci tím, že se vyhnete oddílům, které nejsou v pořádku, a zajistíte směrování požadavků do zdravějších oblastí.
    • Kompromis: Neúčtují se další náklady na RU, ale můžou stále umožňovat určitou počáteční ztrátu dostupnosti pro požadavky, které budou mít za následek vypršení časového limitu sítě.
    • Případ použití: Ideální pro úlohy náročné na zápis nebo smíšené úlohy, kde je nezbytný konzistentní výkon, zejména při práci s oddíly, které můžou občas být v pořádku.

Obě strategie je možné použít společně k vylepšení dostupnosti čtení a zápisu a snížení koncové latence. Jistič na úrovni oddílů může zpracovávat různé přechodné scénáře selhání, včetně těch, které můžou vést k pomalému provádění replik, aniž by bylo nutné provádět paralelní požadavky. Přidání strategie dostupnosti založené na prahových hodnotách navíc dále minimalizuje koncovou latenci a eliminuje ztrátu dostupnosti, pokud jsou přijatelné další náklady na RU.

Díky implementaci těchto strategií můžou vývojáři zajistit, aby jejich aplikace zůstaly odolné, udržovaly vysoký výkon a poskytovaly lepší uživatelské prostředí i během regionálních výpadků nebo podmínek s vysokou latencí.

Konzistence relací s vymezeným oborem oblastí

Přehled

Další informace o nastavení konzistence obecně najdete v tématu Úrovně konzistence ve službě Azure Cosmos DB. Sada Java SDK poskytuje optimalizaci pro konzistenci relací pro účty pro zápis do více oblastí tím, že umožňuje jejich obor. To zvyšuje výkon tím, že snižuje latenci replikace mezi oblastmi prostřednictvím minimalizace opakování na straně klienta. Toho dosáhnete tak, že místo globálně spravujete tokeny relací na úrovni oblasti. Pokud je v aplikaci možné omezit konzistenci na menší počet oblastí implementací konzistence relací v rozsahu oblastí, můžete dosáhnout lepšího výkonu a spolehlivosti operací čtení a zápisu v účtech s více zápisy minimalizací zpoždění replikace mezi oblastmi a opakování.

Zaměstnanecké výhody

  • Nižší latence: Lokalizací ověřování tokenu relace na úrovni oblasti se sníží pravděpodobnost nákladných opakovaných pokusů napříč oblastmi.
  • Vylepšený výkon: Minimalizuje dopad regionálního převzetí služeb při selhání a prodlevy replikace a nabízí vyšší konzistenci čtení a zápisu a nižší využití procesoru.
  • Optimalizované využití prostředků: Snižuje zatížení procesoru a sítě u klientských aplikací omezením potřeby opakovaných pokusů a volání mezi oblastmi, čímž optimalizuje využití prostředků.
  • Vysoká dostupnost: Udržováním tokenů relací v rozsahu oblastí můžou aplikace dál fungovat hladce i v případě, že některé oblasti mají vyšší latenci nebo dočasná selhání.
  • Záruky konzistence: Zajišťuje, aby byly záruky konzistence relace (čtení zápisu, monotónní čtení) spolehlivěji splněny bez zbytečných opakování.
  • Efektivita nákladů: Snižuje počet volání mezi oblastmi, což potenciálně snižuje náklady spojené s přenosy dat mezi oblastmi.
  • Škálovatelnost: Umožňuje aplikacím efektivněji škálovat snížením kolizí a režijních nákladů spojených s údržbou globálního tokenu relace, zejména v nastaveních s více oblastmi.

Kompromisy

  • Zvýšené využití paměti: Filtr bloom a úložiště tokenů relací specifické pro oblast vyžadují další paměť, což může být důležité pro aplikace s omezenými prostředky.
  • Složitost konfigurace: Vyladění očekávaného počtu vložení a falešně pozitivní míry pro filtr květu přidá do procesu konfigurace vrstvu složitosti.
  • Potenciál falešně pozitivních výsledků: I když filtr kvetu minimalizuje opakování mezi oblastmi, stále existuje mírná šance, že falešně pozitivní výsledky ovlivní ověření tokenu relace, i když je možné rychlost řídit. Falešně pozitivní znamená, že se vyřeší token globální relace, čímž se zvýší pravděpodobnost opakování mezi oblastmi, pokud se místní oblast nedostavila k této globální relaci. Záruky relací jsou splněny i v přítomnosti falešně pozitivních výsledků.
  • Použitelnost: Tato funkce je nejužitevější pro aplikace s vysokou kardinalitou logických oddílů a pravidelným restartováním. U aplikací s menším počtem logických oddílů nebo občasných restartování nemusí docházet k významným výhodám.

Jak to funguje

Nastavení tokenu relace

  1. Dokončení požadavku: Po dokončení požadavku sada SDK zachytí token relace a přidruží ho k oblasti a klíči oddílu.
  2. Úložiště na úrovni oblasti: Tokeny relace se ukládají do vnořeného ConcurrentHashMap objektu, který udržuje mapování mezi rozsahy klíčů oddílů a průběhem na úrovni oblasti.
  3. Bloom Filter: Filtr kvetu sleduje, které oblasti byly přístupné jednotlivými logickými oddíly, což pomáhá lokalizovat ověřování tokenů relace.

Řešení tokenu relace

  1. Inicializace požadavku: Před odesláním požadavku se sada SDK pokusí přeložit token relace pro příslušnou oblast.
  2. Kontrola tokenu: Token se kontroluje na základě dat specifických pro danou oblast, aby se zajistilo, že se požadavek směruje na nejaktuálnější repliku.
  3. Logika opakování: Pokud se token relace neověřuje v rámci aktuální oblasti, sada SDK opakuje pokusy s jinými oblastmi, ale vzhledem k lokalizovaným úložišti je to méně časté.

Použití sady SDK

Tady je postup, jak inicializovat CosmosClient s konzistencí relací v rozsahu oblasti:

CosmosClient client = new CosmosClientBuilder()
    .endpoint("<your-endpoint>")
    .key("<your-key>")
    .consistencyLevel(ConsistencyLevel.SESSION)
    .buildClient();

// Your operations here

Povolit konzistenci relací v oboru oblastí

Pokud chcete povolit zachytávání relací v oboru oblasti ve vaší aplikaci, nastavte následující systémovou vlastnost:

System.setProperty("COSMOS.SESSION_CAPTURING_TYPE", "REGION_SCOPED");

Konfigurace filtru bloom

Vylaďte výkon konfigurací očekávaných vložení a falešně pozitivního poměru pro filtr kvetu:

System.setProperty("COSMOS.PK_BASED_BLOOM_FILTER_EXPECTED_INSERTION_COUNT", "5000000"); // adjust as needed
System.setProperty("COSMOS.PK_BASED_BLOOM_FILTER_EXPECTED_FFP_RATE", "0.001"); // adjust as needed
System.setProperty("COSMOS.SESSION_CAPTURING_TYPE", "REGION_SCOPED");
System.setProperty("COSMOS.PK_BASED_BLOOM_FILTER_EXPECTED_INSERTION_COUNT", "1000000");
System.setProperty("COSMOS.PK_BASED_BLOOM_FILTER_EXPECTED_FFP_RATE", "0.01");

Důsledky pro paměť

Níže je zachovaná velikost (velikost objektu a to, na čem závisí) interního kontejneru relací (spravovaném sadou SDK) s různými očekávanými vloženími do filtru květů.

Očekávané vložení Míra falešně pozitivních Zachovaná velikost
10, 000 0,001 21 kB
100, 000 0,001 183 kB
1 milion 0,001 1,8 MB
10 milionů 0,001 17,9 MB
100 milionů 0,001 179 MB
1 miliarda 0,001 1,8 GB

Důležité

Abyste mohli aktivovat konzistenci relací v rozsahu oblastí, musíte používat verzi 4.60.0 sady Java SDK nebo vyšší.

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 project reactor, rozhraní Reactive Streams použité k implementaci asynchronního rozhraní API sady 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.