Az Azure Cosmos DB és a .NET teljesítményével kapcsolatos tippek

A KÖVETKEZŐRE VONATKOZIK: NoSQL

Az Azure Cosmos DB egy gyors, rugalmas elosztott adatbázis, amely zökkenőmentesen méretezhető a garantált késéssel és átviteli sebességgel. Nem kell jelentős architektúramódosításokat végeznie, és nem kell összetett kódot írnia az adatbázis Azure Cosmos DB-vel való skálázásához. A vertikális fel- és leskálázás ugyanolyan egyszerű, mint egyetlen API-hívás. További információkért lásd a tároló átviteli sebességének kiépítését vagy az adatbázis átviteli sebességének kiépítését.

Mivel az Azure Cosmos DB hálózati hívásokon keresztül érhető el, az SQL .NET SDK használatakor ügyféloldali optimalizálásokat végezhet a csúcsteljesítmény elérése érdekében.

Ha javítani szeretné az adatbázis teljesítményét, vegye figyelembe az alábbi szakaszokban ismertetett lehetőségeket.

Üzemeltetési javaslatok

A kiszolgálóoldali szemétgyűjtés bekapcsolása

A szemétgyűjtés gyakoriságának csökkentése bizonyos esetekben segíthet. A .NET-ben állítsa a gcServer értéket a következőre true: .

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

Ha nagy átviteli sebességgel vagy másodpercenként 50 000 kérelemegységnél (RU/s) nagyobb sebességgel tesztel, az ügyfélalkalmazás a számítási feladatok szűk keresztmetszetévé válhat. Ennek az az oka, hogy a gép túllépheti a processzor- vagy hálózati kihasználtságot. Ha eléri ezt a pontot, tovább küldheti az Azure Cosmos DB-fiókot az ügyfélalkalmazások több kiszolgálón való horizontális felskálázásával.

Megjegyzés

A magas processzorhasználat megnövekedett késést és a kérések időtúllépési kivételét okozhatja.

Metaadat-műveletek

Ne ellenőrizze, hogy létezik-e adatbázis és/vagy tároló a Create...IfNotExistsAsyncRead...Async gyakori elérésű elérési úton és/vagy az elemművelet végrehajtása előtt. Az ellenőrzést csak akkor kell elvégezni az alkalmazás indításakor, ha szükséges, ha azt szeretné, hogy töröljék őket (ellenkező esetben nincs rá szükség). Ezek a metaadat-műveletek további végpontok közötti késést eredményeznek, nem rendelkeznek SLA-val és saját, nem skálázható, adatműveletekhez hasonló korlátozásokkal .

Naplózás és nyomkövetés

Egyes környezetekben engedélyezve van a .NET DefaultTraceListener . A DefaultTraceListener teljesítményproblémákat okoz az éles környezetekben, ami magas processzor- és I/O-szűk keresztmetszeteket okoz. Ellenőrizze és győződjön meg arról, hogy a DefaultTraceListener le van tiltva az alkalmazáshoz úgy, hogy eltávolítja azt a TraceListeners eszközből éles környezetekben.

A legújabb (3.23.0-nál újabb) SDK-verziók automatikusan eltávolítják, amikor észlelik. A régebbi verziók esetén a következő lépésekkel távolíthatja el:

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
}

Hálózatkezelés

Kapcsolati szabályzat: Közvetlen kapcsolati mód használata

A .NET V3 SDK alapértelmezett csatlakozási módja közvetlen TCP protokollal. A kapcsolati módot akkor konfigurálja, amikor létrehozza a példányt a CosmosClient következőben CosmosClientOptions: . A különböző csatlakozási lehetőségekről a kapcsolati módokról szóló cikkből tudhat meg többet.

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

Rövid élettartamú portok elfogyása

Ha magas kapcsolati kötetet vagy magas porthasználatot lát a példányokon, először ellenőrizze, hogy az ügyfélpéldányok egyhangosak-e. Más szóval az ügyfélpéldányoknak egyedinek kell lenniük az alkalmazás teljes élettartama során.

Amikor a TCP protokollon fut, az ügyfél a hosszú élettartamú kapcsolatok használatával optimalizálja a késést. Ez ellentétben áll a HTTPS protokollal, amely két perc inaktivitás után leállítja a kapcsolatokat.

Azokban az esetekben, amikor kevés hozzáféréssel rendelkezik, és az átjáró módú hozzáféréshez képest magasabb kapcsolatszámot észlel, a következőket teheti:

  • Konfigurálja a CosmosClientOptions.PortReuseMode tulajdonságotPrivatePortPool (a keretrendszer 4.6.1-s és újabb verzióival, valamint a .NET Core 2.0-s és újabb verzióival). Ez a tulajdonság lehetővé teszi, hogy az SDK rövid élettartamú portokból álló kis készletet használjon a különböző Azure Cosmos DB-célvégpontokhoz.
  • Konfigurálja a CosmosClientOptions.IdleConnectionTimeout tulajdonságot 10 percnél hosszabb vagy egyenlő értékre. Az ajánlott értékek 20 perctől 24 óráig tartanak.

A teljesítmény érdekében helyezzen el ügyfeleket ugyanabban az Azure-régióban

Ha lehetséges, helyezzen el minden olyan alkalmazást, amely meghívja az Azure Cosmos DB-t ugyanabban a régióban, mint az Azure Cosmos DB-adatbázis. Íme egy hozzávetőleges összehasonlítás: az ugyanabban a régióban lévő Azure Cosmos DB-be irányuló hívások 1 ezredmásodpercben (ms) és 2 ms között fejeződnek be, de az USA nyugati és keleti partja közötti késés meghaladja az 50 ms-ot. Ez a késés kérésenként 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, ha biztosítja, hogy a hívó alkalmazás ugyanabban az Azure-régióban legyen, mint a kiépített Azure Cosmos DB-végpont. Az elérhető régiók listájáért tekintse meg az Azure-régiókat.

Az ügyfeleket ugyanabban a régióban kell összeválogatni.

Szálak/tevékenységek számának növelése

Mivel az Azure Cosmos DB-t a hálózaton keresztül hívhatja meg, előfordulhat, hogy módosítania kell a kérések egyidejűségi fokát, hogy az ügyfélalkalmazás minimális várakozási időt töltsön a kérések között. Ha például a . NET-feladat párhuzamos kódtárát használja, hozzon létre több száz olyan feladat sorrendjében, amelyek az Azure Cosmos DB-ből olvasnak vagy írnak.

Gyorsított hálózatkezelés engedélyezése

A késés és a cpu-jitter csökkentése érdekében javasoljuk, hogy engedélyezze a gyorsított hálózatkezelést az ügyfél virtuális gépein. További információ: Windows rendszerű virtuális gép létrehozása gyorsított hálózatkezeléssel vagy Linux rendszerű virtuális gép létrehozása gyorsított hálózatkezeléssel.

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 meghatározásához és a fejlesztések áttekintéséhez tekintse meg az Azure Cosmos DB SDK-t.

Stream API-k használata

A .NET SDK V3 stream API-kat tartalmaz, amelyek szerializálás nélkül fogadnak és adnak vissza adatokat.

Azok a középső rétegbeli alkalmazások, amelyek nem közvetlenül az SDK-ból származó válaszokat használnak fel, de más alkalmazásszintekre továbbítják őket, a stream API-k előnyeit élvezhetik. A streamkezelésre vonatkozó példákért tekintse meg az elemkezelési mintákat.

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

Minden CosmosClient példány szálbiztos, és hatékony kapcsolatkezelést és cím-gyorsítótárazást végez, ha közvetlen módban működik. A hatékony kapcsolatkezelés és az SDK-ügyfél teljesítményének javítása érdekében azt javasoljuk, hogy az alkalmazás teljes élettartama során egyetlen példányt AppDomain használjon.

Amikor Azure Functions dolgozik, a példányoknak a meglévő irányelveket is követniük kell, és egyetlen példányt kell fenntartaniuk.

A hívások blokkolásának elkerülése

Az Azure Cosmos DB SDK-t úgy kell megtervezni, hogy egyszerre több kérést dolgozzanak fel. Az aszinkron API-k lehetővé teszik, hogy egy kis szálkészlet több ezer egyidejű kérést kezeljen azáltal, hogy nem várakozik a blokkoló hívásokra. Ahelyett, hogy egy hosszú ideig futó szinkron feladatra várna, a szál egy másik kérésen is működhet.

Az Azure Cosmos DB SDK-t használó alkalmazások egyik gyakori teljesítményproblémája az aszinkron hívások blokkolása. Számos szinkron blokkoló hívás a szálkészlet éhezéséhez és a válaszidő romlásához vezet.

Ne tegye a következőt:

  • A Task.Wait vagy a Task.Result meghívásával tiltsa le az aszinkron végrehajtást.
  • A Task.Run használatával aszinkron API-t készíthet.
  • Zárolások beszerzése a közös kódútvonalakban. Az Azure Cosmos DB .NET SDK akkor a legkijátszottabb, ha a kód párhuzamos futtatására van kiosztva.
  • Hívja meg a Task.Run parancsot , és azonnal várja meg. ASP.NET Core már futtatja az alkalmazáskódot normál szálkészlet-szálakon, így a Task.Run meghívása csak felesleges szálkészlet-ütemezést eredményez. Még ha az ütemezett kód blokkolna is egy szálat, a Task.Run ezt nem akadályozza meg.
  • Ne használja a ToList() függvényt Container.GetItemLinqQueryable<T>() , amely blokkoló hívásokat használ a lekérdezés szinkron kiürítéséhez. A ToFeedIterator() használatával aszinkron módon ürítheti a lekérdezést.

Tegye a következőt:

  • Az Azure Cosmos DB .NET API-k aszinkron meghívása.
  • A teljes hívásverem aszinkron, hogy kihasználhassa az aszinkron/várakozási mintákat.

A profilkészítők, például a PerfView segítségével megkereshetők a szálkészlethez gyakran hozzáadott szálak. Az Microsoft-Windows-DotNETRuntime/ThreadPoolWorkerThread/Start esemény azt jelzi, hogy egy szál hozzá van adva a szálkészlethez.

Tartalomválasz letiltása írási műveletek során

A nagy mennyiségű hasznos adatokkal rendelkező számítási feladatok esetében állítsa a EnableContentResponseOnWrite kérelem beállítását a következőre false: . A szolgáltatás többé nem adja vissza a létrehozott vagy frissített erőforrást az SDK-nak. Általában, mivel az alkalmazás rendelkezik a létrehozott objektummal, nem kell a szolgáltatásnak visszaadnia. A fejlécértékek továbbra is elérhetők, például egy kérelemdíj. A tartalomválasz letiltása segíthet a teljesítmény javításában, mivel az SDK-nak már nem kell memóriát lefoglalnia vagy szerializálnia a válasz törzsét. A teljesítmény további elősegítése érdekében csökkenti a hálózati sávszélesség használatát is.

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

A tömeges optimalizálás engedélyezése az átviteli sebesség késleltetés helyett történő optimalizálásához

Engedélyezze a Tömeges beállítást olyan forgatókönyvek esetében, ahol a számítási feladat nagy átviteli sebességet igényel, és a késés nem olyan fontos. A Tömeges funkció engedélyezéséről és a használni kívánt forgatókönyvekről további információt a Bevezetés a tömeges támogatásba című témakörben talál.

Gazdagépenkénti System.Net MaxConnections számának növelése átjáró mód használatakor

Az Azure Cosmos DB-kérések HTTPS-en/REST-en keresztül, átjáró mód használatakor lesznek intézve. Gazdagépnévre vagy IP-címre vonatkozó alapértelmezett kapcsolati korlát vonatkozik rájuk. Előfordulhat, hogy magasabb értéket kell beállítania MaxConnections (100 és 1000 között), hogy az ügyfélkódtár több egyidejű kapcsolatot használjon az Azure Cosmos DB-hez. A .NET SDK 1.8.0-s és újabb verzióiban a ServicePointManager.DefaultConnectionLimit alapértelmezett értéke 50. Az érték módosításához beállíthat Documents.Client.ConnectionPolicy.MaxConnectionLimit egy magasabb értéket.

Szálak/tevékenységek számának növelése

Lásd a cikk Hálózatkezelés szakaszában található szálak/feladatok számának növelését ismertető szakaszt.

Lekérdezési műveletek

A lekérdezési műveletekhez tekintse meg a lekérdezések teljesítményével kapcsolatos 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 azt is lehetővé teszi, hogy indexelési útvonalak (IndexingPolicy.IncludedPaths és IndexingPolicy.ExcludedPaths) használatával adja meg, hogy mely dokumentumelérési utakat foglalja bele vagy zárja ki az indexelésből.

Csak a szükséges elérési utak indexelésével javíthatja az írási teljesítményt, csökkentheti az írási műveletek kérelemegység-díjait, és csökkentheti az indextárolást olyan forgatókönyvek esetében, amelyekben a lekérdezési minták előre ismertek. Ennek az az oka, hogy az indexelési költségek közvetlenül kapcsolódnak az indexelt egyedi elérési utak számához. Az alábbi kód például bemutatja, hogyan zárhatja ki a dokumentumok egy teljes szakaszát (egy részhalmazt) az indexelésből a "*" helyettesítő karakterrel:

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

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

Teljesítmény

Alacsonyabb RU/s-használat mérése és finomhangolása

Az Azure Cosmos DB számos adatbázis-műveletet kínál. Ezek a műveletek magukban foglalják az univerzális lemezformátumú (UDF) fájlokat tartalmazó relációs és hierarchikus lekérdezéseket, a tárolt eljárásokat és az eseményindítókat, valamint az adatbázis-gyűjteményben lévő dokumentumokon futó összes műveletet.

Az egyes műveletekhez kapcsolódó költségek a művelet végrehajtásához szükséges processzortól, I/O-tól és memóriától függően változnak. A hardveres erőforrások átgondolása és kezelése helyett a kérelemegységek a különböző adatbázis-műveletek végrehajtásához és az alkalmazáskérések kiszolgálásához szükséges erőforrások egyetlen mértékeként is felfoghatók.

Az átviteli sebesség kiépítése az egyes tárolókhoz beállított kérelemegységek száma alapján történik. A kérelemegység-felhasználás másodpercenkénti egységárként lesz kiértékelve. Azok az alkalmazások, amelyek túllépik a tárolóhoz kiosztott kérelemegységek sebességét, mindaddig korlátozottak, amíg a sebesség a tárolóhoz kiosztott szint alá nem csökken. 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és összetettsége hatással van arra, hogy egy művelethez hány kérelemegység szükséges. A predikátumok száma, a predikátumok jellege, az UDF-fájlok száma és a forrásadatkészlet mérete mind hatással van a lekérdezési műveletek költségeire.

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 (vagy a .NET SDK-ban ResourceResponse<T> vagy FeedResponse<T> annak megfelelő RequestCharge tulajdonságát) a műveletek által felhasznált kérelemegységek számának méréséhez:

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

Az ebben a fejlécben visszaadott kérelemdíj a kiosztott átviteli sebesség töredéke (azaz 2000 RU/s). Ha például az előző lekérdezés 1000 1 KB 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 korlátozza a későbbi kéréseket. További információ: Kérelemegységek és a kérelemegység-kalkulátor.

Sebességkorlátozás/túl nagy kérelemmennyiség kezelése

Ha egy ügyfél megkísérli túllépni egy fiók fenntartott átviteli sebességét, a kiszolgálón nem romlik a teljesítmény, és nem használja az átviteli kapacitást a fenntartott szinten túl. A kiszolgáló a kérést a RequestRateTooLarge (HTTP-állapotkód: 429) előtaggal zárja le. Egy x-ms-retry-after-ms fejlécet ad vissza, amely azt az időt jelzi ezredmásodpercben, amellyel a felhasználónak várnia kell a kérés ismételt megkísérlé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 több ügyfél egyidejűleg éri el, 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 CosmosException kivételt ad vissza, amelynek állapotkódja 429.

Az alapértelmezett újrapróbálkozás-számot a példányon CosmosClientOptions való beállítással RetryOptions módosíthatja. Alapértelmezés szerint a 429-es állapotkódú CosmosException 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 a hiba akkor is megjelenik, ha az újrapróbálkozás aktuális száma kisebb, mint a maximális újrapróbálkozás-szám, függetlenül attól, hogy az aktuális érték az alapértelmezett 9 vagy egy felhasználó által megadott érték.

Az automatikus újrapróbálkozás működése segít a legtöbb alkalmazás rugalmasságának és használhatóságának javításában. Előfordulhat azonban, hogy nem ez a legjobb viselkedés teljesítménymutatók használatakor, különösen akkor, ha a késést méri. Az ügyfél által megfigyelt késés megnövekedik, ha a kísérlet eléri a kiszolgáló szabályozását, és az ügyféloldali SDK csendes újrapróbálkozást okoz. A teljesítménykísérletek során tapasztalható késési csúcsok elkerülése érdekében mérje meg az egyes műveletek által visszaadott díjakat, és győződjön meg arról, hogy a kérések a fenntartott kérelemmennyiség alatt működnek.

További információ: Kérelemegységek.

A nagyobb átviteli sebesség érdekében tervezzen kisebb dokumentumokhoz

Egy adott művelet kérelemdíja (vagyis a kérelemfeldolgozási költség) közvetlenül összefügg a dokumentum méretével. A nagyméretű dokumentumokon végzett műveletek többe kerülnek, mint a kis méretű dokumentumokon végzett műveletek.

Következő lépések

Az Azure Cosmos DB néhány ügyfélgépen történő nagy teljesítményű forgatókönyveinek kiértékelésére használt mintaalkalmazásért tekintse meg az Azure Cosmos DB teljesítmény- és méretezési tesztelését.

Az alkalmazás méretezésre és nagy teljesítményre való tervezésével kapcsolatos további információkért lásd: Particionálás és skálázás az Azure Cosmos DB-ben.