Teljesítménnyel kapcsolatos tippek az Azure Cosmos DB Java SDK v4-hez

A KÖVETKEZŐRE VONATKOZIK: NoSQL

Fontos

A cikkben szereplő teljesítménytippek csak az Azure Cosmos DB Java SDK v4-hez tartoznak. További információért tekintse meg az Azure Cosmos DB Java SDK v4 kiadási megjegyzéseit, a Maven-adattárat és az Azure Cosmos DB Java SDK v4 hibaelhárítási útmutatóját . Ha jelenleg a v4-es verziónál régebbi verziót használ, a v4-re való frissítésről a Migrálás az Azure Cosmos DB Java SDK v4-es verziójára című útmutatóban olvashat.

Az Azure Cosmos DB egy gyors és rugalmas elosztott adatbázis, amely zökkenőmentesen méretezhető, garantált késéssel és átviteli sebességgel. Nem kell jelentős architektúramódosításokat végeznie, vagy összetett kódot kell írnia az adatbázis Azure Cosmos DB-vel való skálázásához. A vertikális fel- és leskálázás olyan egyszerű, mint egyetlen API-hívás vagy SDK-metódushívás. Mivel azonban az Azure Cosmos DB hálózati hívásokon keresztül érhető el, ügyféloldali optimalizálásokkal érheti el a csúcsteljesítményt az Azure Cosmos DB Java SDK v4 használatakor.

Ha tehát a "Hogyan javíthatom az adatbázis teljesítményét?" kérdésre válaszol, vegye figyelembe a következő lehetőségeket:

Hálózat

  • Ügyfelek rendezése ugyanabban az Azure-régióban a teljesítmény érdekében

Ha lehetséges, helyezze az Azure Cosmos DB-t hívó alkalmazásokat ugyanabban a régióban, mint az Azure Cosmos DB-adatbázis. Hozzávetőleges összehasonlításként az ugyanazon régión belül az Azure Cosmos DB-be irányuló hívások 1–2 ms-on belül befejeződnek, de az USA >nyugati és keleti partja közötti késés 50 ms. Ez a késés valószínűleg a kéréstől függően változhat attól függően, hogy a kérés milyen útvonalon halad át az ügyfélről az Azure-adatközpont határára. A lehető legkisebb késést úgy érheti el, hogy a hívó alkalmazás ugyanabban az Azure-régióban található, mint a kiépített Azure Cosmos DB-végpont. Az elérhető régiók listáját az Azure-régiók című témakörben találja.

Az Azure Cosmos DB kapcsolati szabályzatának illusztrációja

A többrégiós Azure Cosmos DB-fiókkal együttműködő alkalmazásoknak előnyben részesített helyeket kell konfigurálnia, hogy a kérések egy csoportosított régióba kerülhessenek.

Gyorsított hálózatkezelés engedélyezése a késés és a PROCESSZOR-jitter csökkentése érdekében

Határozottan javasoljuk, hogy kövesse az utasításokat a gyorsított hálózatkezelés engedélyezéséhez a Windowsban (válassza az utasításokat) vagy a Linux (utasítások kiválasztása) Azure-beli virtuális gép számára, hogy maximalizálja a teljesítményt a késés és a cpu-jitter csökkentésével.

Gyorsított hálózatkezelés nélkül előfordulhat, hogy az Azure-beli virtuális gép és más Azure-erőforrások között áthaladó IO-t a virtuális gép és a hálózati kártya között található gazdagép és virtuális kapcsoló irányítja át. Miután a gazdagép és a virtuális kapcsoló beágyazott a datapathban, nem csak növeli a késést és a kommunikáció csatornán belüli jittert, hanem a processzorciklusokat is ellopja a virtuális gépről. A gyorsított hálózatkezeléssel a virtuális gép közvetlenül a hálózati adapterhez kapcsolódik közvetítők nélkül. A hálózati házirend minden részletét a hálózati adapter hardverén kezeli a rendszer, megkerülve a gazdagépet és a virtuális kapcsolót. A gyorsított hálózatkezelés engedélyezésekor általában alacsonyabb késésre és nagyobb átviteli sebességre, valamint konzisztensebb késésre és csökkentett processzorhasználatra számíthat.

Korlátozások: A gyorsított hálózatkezelést támogatni kell a virtuálisgép-operációs rendszeren, és csak akkor lehet engedélyezni, ha a virtuális gép leállt és felszabadítva van. A virtuális gép nem telepíthető az Azure Resource Managerrel. Az App Service-ben nincs engedélyezve gyorsított hálózat.

További információt a Windows és a Linux utasításokban talál.

Közvetlen és átjárókapcsolat konfigurációjának finomhangolása

A közvetlen és az átjáró módú kapcsolat konfigurációinak optimalizálásához tekintse meg, hogyan hangolhatja a Java SDK v4-hez tartozó kapcsolatkonfigurációkat.

SDK-használat

  • A legújabb SDK telepítése

Az Azure Cosmos DB SDK-k folyamatosan fejlődnek a legjobb teljesítmény érdekében. A legújabb SDK-fejlesztések meghatározásához látogasson el az Azure Cosmos DB SDK-ba.

  • Egyetlen azure Cosmos DB-ügyfél használata az alkalmazás teljes élettartama alatt

Minden Azure Cosmos DB-ügyfélpéldány szálbiztos, és hatékony kapcsolatkezelést és -cím-gyorsítótárazást végez. Annak érdekében, hogy az Azure Cosmos DB-ügyfél hatékony kapcsolatkezelést és jobb teljesítményt biztosíthasson, határozottan javasoljuk az Azure Cosmos DB-ügyfél egyetlen példányának használatát az alkalmazás teljes élettartama alatt.

  • Az alkalmazáshoz szükséges legalacsonyabb konzisztenciaszint használata

CosmosClient létrehozásakor a munkamenet az alapértelmezett konzisztencia, ha nincs explicit módon beállítva. Ha az alkalmazáslogika nem követeli meg a munkamenet konzisztenciáját, állítsa a Konzisztencia végleges értékre. Megjegyzés: ajánlott legalább munkamenet-konzisztenciát használni az Azure Cosmos DB változáscsatorna-feldolgozót alkalmazó alkalmazásokban.

  • A kiosztott átviteli sebesség maximális kihasználása az Async API használatával

Az Azure Cosmos DB Java SDK v4 csomagban két API található, a szinkron és az aszinkron. Nagyjából az Async API SDK-funkciókat implementál, míg a Sync API egy vékony burkoló, amely blokkolja az Async API-ba irányuló hívásokat. Ez ellentétben áll a régebbi Azure Cosmos DB Async Java SDK v2-sel, amely csak aszinkron volt, és a régebbi Azure Cosmos DB Sync Java SDK v2-sel, amely csak Szinkronizálás volt, és külön implementációval rendelkezett.

Az API kiválasztása az ügyfél inicializálása során történik; A CosmosAsyncClient az Async API-t, míg a CosmosClient a Sync API-t támogatja.

Az Async API nem tiltó IO-t implementál, és optimális választás, ha a cél az átviteli sebesség maximális kihasználása az Azure Cosmos DB-nek küldött kérések kiadásakor.

A Sync API használata megfelelő választás lehet, ha olyan API-t szeretne vagy igényel, amely blokkolja az egyes kérésekre adott választ, vagy ha a szinkron művelet az alkalmazás domináns paradigma. Előfordulhat például, hogy a Sync API-t akkor szeretné, ha egy mikroszolgáltatás-alkalmazásban az Adatokat az Azure Cosmos DB-ben tartja, feltéve, hogy az átviteli sebesség nem kritikus.

Vegye figyelembe, hogy a szinkronizálási API átviteli sebessége csökken a kérelmek válaszidejének növelésével, míg az Async API képes a hardver teljes sávszélesség-kapacitásának telítettségére.

A földrajzi rendezés nagyobb és konzisztensebb átviteli sebességet biztosíthat a Sync API használatakor (lásd : Ügyfelek rendezése ugyanabban az Azure-régióban a teljesítmény szempontjából), de továbbra sem várható, hogy meghaladja az Async API elérhető átviteli sebességét.

Előfordulhat, hogy egyes felhasználók nem ismerik a Project Reactort, az Azure Cosmos DB Java SDK v4 Async API implementálásához használt Reaktív adatfolyamok keretrendszert. Ha ez aggodalomra ad okot, javasoljuk, hogy olvassa el a bevezető reactor minta útmutatót , majd tekintse meg ezt a Bevezetés a reaktív programozásba , hogy megismerje magát. Ha már használta az Azure Cosmos DB-t aszinkron felülettel, és a használt SDK az Azure Cosmos DB Async Java SDK v2 volt, akkor lehet, hogy ismeri a ReactiveX/RxJava-t, de nem biztos benne, hogy mi változott a Project Reactorban. Ebben az esetben tekintse meg a Reactor vs. RxJava útmutatót, hogy megismerkedjen.

Az alábbi kódrészletek bemutatják, hogyan inicializálhatja az Azure Cosmos DB-ügyfelet az Async API-hoz vagy a Sync API-művelethez:

Java SDK V4 (Maven com.azure::azure-cosmos) Async API


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

  • Az ügyfél-számítási feladatok vertikális felskálázása

Ha magas átviteli sebességen tesztel, az ügyfélalkalmazás szűk keresztmetszetté válhat a processzor- vagy hálózatkihasználtság miatt. Ha eléri ezt a pontot, folytathatja az Azure Cosmos DB-fiók további leküldését az ügyfélalkalmazások több kiszolgálón való skálázásával.

A jó hüvelykujjszabály az, hogy egy adott kiszolgálón ne lépje túl >az 50%-os processzorhasználatot, hogy a késés alacsony maradjon.

  • Megfelelő ütemező használata (Az eseményhurok IO Netty-szálainak ellopásának elkerülése)

Az Azure Cosmos DB Java SDK aszinkron funkciója a netty non-blocking IO-n alapul. Az SDK rögzített (a gép processzormagjainak számával egyező) számú IO-eseményhurok Netty-szálat használ az IO-műveletek végrehajtásához. Az API által visszaadott Flux a megosztott IO-eseményhurok Netty-szálak egyikén adja ki az eredményt. Ezért fontos, hogy a megosztott IO-eseményhurok Netty-szálak ne legyenek blokkolva. A processzorigényes munka vagy az IO-eseményhurok hálós szálon történő blokkolása holtpontot okozhat, vagy jelentősen csökkentheti az SDK átviteli sebességét.

Az alábbi kód például processzorigényes munkát hajt végre az eseményhurok IO netty szálán:


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();
        });


Az eredmény beérkezése után kerülnie kell az eseményhurok IO netty szálán végzett processzorigényes munkát. Ehelyett saját Ütemezőt adhat meg, hogy saját szálat biztosítson a munkája futtatásához, ahogy az alább látható (szükséges 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();
                });

A munka típusától függően a megfelelő meglévő Reactor Schedulert kell használnia a munkájához. Olvassa el itt Schedulers.

A Project Reactor menetelési és ütemezési modelljének további megismeréséhez tekintse meg a Project Reactor blogbejegyzését.

Az Azure Cosmos DB Java SDK v4-ről további információt a GitHubon található Azure SDK for Java monorepo Azure Cosmos DB-címtárában talál.

  • Naplózási beállítások optimalizálása az alkalmazásban

Különböző okokból olyan naplózást kell hozzáadnia egy szálhoz, amely nagy kérés-átviteli sebességet generál. Ha a cél egy tároló kiosztott átviteli teljesítményének teljes telítettségére a szál által generált kérésekkel, a naplózás optimalizálása nagyban javíthatja a teljesítményt.

  • Aszinkron naplózó konfigurálása

A szinkron naplózó késése szükségszerűen figyelembe veszi a kérés-generáló szál teljes késésének kiszámítását. A log4j2-hez hasonló aszinkron naplózó használata ajánlott a naplózási többletterhelés leválasztásához a nagy teljesítményű alkalmazásszálaktól.

  • Netty naplózásának letiltása

A Netty-kódtár naplózása beszédes, és ki kell kapcsolni (a konfigurációba való bejelentkezés letiltása nem feltétlenül elegendő) a további CPU-költségek elkerülése érdekében. Ha nem hibakeresési módban van, tiltsa le teljesen a Netty naplózását. Ha tehát a Log4j használatával távolítja el a nettyből org.apache.log4j.Category.callAppenders() felmerülő további CPU-költségeket, adja hozzá a következő sort a kódbázishoz:

org.apache.log4j.Logger.getLogger("io.netty").setLevel(org.apache.log4j.Level.OFF);
  • Operációs rendszer – Fájlok erőforráskorlátja

Egyes Linux-rendszerek (például a Red Hat) felső határt szabnak a megnyitott fájlok számának, így a kapcsolatok teljes számának. Futtassa a következőt az aktuális korlátok megtekintéséhez:

ulimit -a

A megnyitott fájlok (nofile) számának elég nagynak kell lennie ahhoz, hogy elegendő hely legyen a konfigurált kapcsolatkészlet méretéhez és az operációs rendszer által megnyitott egyéb fájlokhoz. Módosítható, hogy nagyobb kapcsolatkészletméretet biztosíthasson.

Nyissa meg a limits.conf fájlt:

vim /etc/security/limits.conf

Adja hozzá/módosítsa a következő sorokat:

* - nofile 100000
  • Partíciókulcs megadása pontírásokban

A pontírások teljesítményének javítása érdekében adja meg az elem partíciókulcsát a pontírási API-hívásban, az alábbiak szerint:

Java SDK V4 (Maven com.azure::azure-cosmos) Async API

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

Ahelyett, hogy csak az elempéldányt adja meg, az alábbiak szerint:

Java SDK V4 (Maven com.azure::azure-cosmos) Async API

asyncContainer.createItem(item).block();

Ez utóbbi támogatott, de késést fog hozzáadni az alkalmazáshoz; Az SDK-nak elemeznie kell az elemet, és ki kell nyernie a partíciókulcsot.

Lekérdezési műveletek

A lekérdezési műveletekhez tekintse meg a lekérdezések teljesítményére vonatkozó tippeket.

Indexelési szabályzat

  • Nem használt útvonalak kizárása az indexelésből a gyorsabb írás érdekében

Az Azure Cosmos DB indexelési szabályzata lehetővé teszi, hogy az Indexelési útvonalak (setIncludedPaths és setExcludedPaths) használatával megszűrje, hogy mely dokumentumelérési utakat vegye fel vagy zárja ki az indexelésből. Az indexelési útvonalak használata jobb írási teljesítményt és alacsonyabb indextárolást kínálhat azokhoz a forgatókönyvekhez, amelyekben a lekérdezési minták előre ismertek, mivel az indexelési költségek közvetlenül korrelálnak az indexelt egyedi útvonalak számával. Az alábbi kód például azt mutatja be, hogyan lehet a dokumentumok teljes szakaszait (más néven részösszeget) belefoglalni és kizárni az indexelésből a "*" helyettesítő karakterrel.


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);

További információ: Azure Cosmos DB indexelési szabályzatok.

Átfutás

  • Kisebb kérelemegységek/másodperces használat mérése és finomhangolása

Az Azure Cosmos DB számos adatbázisműveletet kínál, beleértve a relációs és hierarchikus lekérdezéseket az UDF-ekkel, a tárolt eljárásokat és az eseményindítókat – mind az adatbázis-gyűjtemény dokumentumain. Az egyes ilyen műveletekhez kapcsolódó költségek a művelet végrehajtásához szükséges CPU, IO és memória függvényében változnak. A hardvererőforrások átgondolása és kezelése helyett egyetlen mértékként tekinthet a kérelemegységre (RU) a különböző adatbázis-műveletek végrehajtásához és az alkalmazáskérelmek kiszolgálásához szükséges erőforrásokhoz.

Az átviteli sebesség az egyes tárolókhoz beállított kérelemegységek száma alapján van kiépítve. A kérelemegység-felhasználás másodpercenkénti sebességként lesz kiértékelve. A tárolóhoz kiosztott kérelemegység-mértéket meghaladó alkalmazások korlátozottak, amíg a sebesség nem csökken a tárolóhoz kiosztott szint alá. Ha az alkalmazás magasabb átviteli sebességet igényel, további kérelemegységek kiépítésével növelheti az átviteli sebességet.

A lekérdezések összetettsége hatással van arra, hogy egy művelet hány kérelemegységet használ fel. A predikátumok száma, a predikátumok jellege, az UDF-ek száma és a forrásadatkészlet mérete mind befolyásolják a lekérdezési műveletek költségeit.

Bármely művelet (létrehozás, frissítés vagy törlés) többletterhelésének méréséhez vizsgálja meg az x-ms-request-charge fejlécet a műveletek által felhasznált kérelemegységek számának méréséhez. A ResourceResponse T vagy a FeedResponse<T>> egyenértékű RequestCharge tulajdonságát<is megtekintheti.

Java SDK V4 (Maven com.azure::azure-cosmos) Async API

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

response.getRequestCharge();

Az ebben a fejlécben visszaadott kérelemdíj a kiosztott átviteli sebesség töredékét adja. Ha például 2000 RU/s van kiépítve, és ha az előző lekérdezés 1000 1 KB-os dokumentumot ad vissza, a művelet költsége 1000. Így egy másodpercen belül a kiszolgáló csak két ilyen kérést tart tiszteletben, mielőtt a sebesség korlátozza a későbbi kéréseket. További információ: Kérelemegységek és a kérelemegység-kalkulátor.

  • Túl nagy sebességkorlátozás/kérési sebesség kezelése

Amikor egy ügyfél megkísérli túllépni egy fiók fenntartott átviteli sebességét, a kiszolgálón nincs teljesítménycsökkenés, és az átviteli kapacitás használata nem lépi túl a fenntartott szintet. A kiszolgáló előzetesen a RequestRateTooLarge (HTTP-állapotkód: 429) paranccsal fejezi be a kérést, és visszaadja az x-ms-retry-after-ms fejlécet, amely azt jelzi, hogy a felhasználónak ezredmásodpercben mennyi időt kell várnia a kérés újbóli megismétlése előtt.

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

Az SDK-k implicit módon elkapják ezt a választ, tiszteletben tartják a kiszolgáló által megadott újrapróbálkozási fejlécet, és újrapróbálkoznak a kéréssel. Ha a fiókját nem éri el egyszerre több ügyfél, a következő újrapróbálkozás sikeres lesz.

Ha több ügyfél kumulatív működése következetesen meghaladja a kérések arányát, előfordulhat, hogy az ügyfél által jelenleg 9-re beállított alapértelmezett újrapróbálkozási szám nem elegendő; ebben az esetben az ügyfél egy CosmosClientException 429-s állapotkódot ad az alkalmazásnak. Az alapértelmezett újrapróbálkozás száma a példány használatával setMaxRetryAttemptsOnThrottledRequests()ThrottlingRetryOptions módosítható. Alapértelmezés szerint a 429-es állapotkódú CosmosClientException 30 másodperces kumulatív várakozási idő után lesz visszaadva, ha a kérés továbbra is a kérési sebesség felett működik. Ez akkor is előfordul, ha az újrapróbálkozások aktuális száma kisebb, mint a maximális újrapróbálkozások száma, legyen az alapértelmezett érték 9 vagy felhasználó által megadott érték.

Bár az automatikus újrapróbálkozási viselkedés segít javítani a rugalmasságot és a használhatóságot a legtöbb alkalmazás esetében, a teljesítménymutatók használatakor előfordulhat, különösen a késés mérése során. Az ügyfél által megfigyelt késés megnő, ha a kísérlet eléri a kiszolgálót, és az ügyfél SDK-jának csendes újrapróbálkozását okozza. A teljesítménykísérletek során fellépő késési csúcsok elkerülése érdekében mérje meg az egyes műveletek által visszaadott díjat, és győződjön meg arról, hogy a kérések a fenntartott kérések aránya alatt működnek. További információ: Kérelemegységek.

  • Kisebb dokumentumok tervezése a nagyobb átviteli sebesség érdekében

Egy adott művelet kérelemdíja (a kérelem feldolgozási költsége) közvetlenül korrelál a dokumentum méretével. A nagyméretű dokumentumokon végzett műveletek többe kerülnek, mint a kis méretű dokumentumok műveletei. Ideális esetben úgy kell létrehoznia az alkalmazást és a munkafolyamatokat, hogy az elem mérete ~1 KB legyen, vagy hasonló sorrendben vagy nagyságrendben. A késésre érzékeny alkalmazások esetében kerülni kell a nagyméretű elemeket – a több MB-os dokumentumok lelassítják az alkalmazást.

Következő lépések

Ha többet szeretne megtudni az alkalmazás méretezéshez és nagy teljesítményhez való tervezéséről, tekintse meg a particionálást és a skálázást az Azure Cosmos DB-ben.

Kapacitástervezést szeretne végezni az Azure Cosmos DB-be való migráláshoz? A kapacitástervezéshez használhatja a meglévő adatbázisfürt adatait.