Lassú kérések diagnosztizálása és hibaelhárítása az Azure Cosmos DB .NET SDK-ban

A KÖVETKEZŐRE VONATKOZIK: NoSQL

Az Azure Cosmos DB-ben lassú kéréseket tapasztalhat. A késések több okból is előfordulhatnak, például a kérések szabályozása vagy az alkalmazás kialakításának módja. Ez a cikk a probléma különböző kiváltó okait ismerteti.

Túl magas kérelemmennyiség

A kérelmek szabályozása a lassú kérések leggyakoribb oka. Az Azure Cosmos DB szabályozza a kéréseket, ha túllépik az adatbázis vagy tároló lefoglalt kérelemegységeit. Az SDK beépített logikával rendelkezik a kérések újrapróbálkozásához. A túl nagy kérelemarányú hibaelhárítási cikkből megtudhatja, hogyan ellenőrizheti, hogy a kérések szabályozva vannak-e. A cikk azt is ismerteti, hogyan skálázhatja a fiókját, hogy a jövőben elkerülhesse ezeket a problémákat.

Az alkalmazás kialakítása

Az alkalmazás tervezésekor kövesse a .NET SDK ajánlott eljárásait a legjobb teljesítmény érdekében. Ha az alkalmazás nem követi az SDK ajánlott eljárásait, lassú vagy sikertelen kéréseket kaphat.

Az alkalmazás fejlesztésekor vegye figyelembe a következőket:

Metaadat-műveletek

Ha ellenőriznie kell, hogy létezik-e adatbázis vagy tároló, ne hívja Create...IfNotExistsAsync meg, vagy Read...Async mielőtt műveletet hajt végre egy elemműveleten. Az érvényesítés csak akkor végezhető el az alkalmazás indításakor, ha szükséges, ha azt szeretné, hogy töröljék őket. Ezek a metaadat-műveletek további késést okoznak, nem rendelkeznek szolgáltatásiszint-szerződéssel (SLA), és külön korlátozásokkal rendelkeznek. Nem úgy skáláznak, mint az adatműveletek.

Lassú kérések tömeges módban

A tömeges mód egy átviteli sebességre optimalizált mód, amely nagy adatmennyiség-műveletekhez készült, nem késésoptimalizált mód; Ez a rendelkezésre álló átviteli sebesség telítettségére szolgál. Ha lassú kéréseket tapasztal tömeges mód használatakor, győződjön meg arról, hogy:

  • Az alkalmazás fordítása kiadási konfigurációban történik.
  • Nem méri a késést az alkalmazás hibakeresése közben (nincs hibakereső csatolva).
  • A műveletek mennyisége magas, ne használjon tömegesen 1000-nél kevesebb művelethez. A kiosztott átviteli sebesség határozza meg, hogy másodpercenként hány műveletet lehet feldolgozni, a cél az lenne, hogy a lehető legtöbb műveletet használjuk fel.
  • A tároló figyelése szabályozási forgatókönyvek esetén. Ha a tároló nagy mértékben szabályozva van, az azt jelenti, hogy az adatok mennyisége nagyobb, mint a kiosztott átviteli sebesség, fel kell skáláznia a tárolót, vagy csökkentenie kell az adatmennyiséget (esetleg egyszerre kisebb adatkötegeket kell létrehoznia).
  • Helyesen használja a mintát az async/awaitösszes egyidejű feladat feldolgozásához , és nem blokkolja az aszinkron műveletet.

A diagnosztikai adatok rögzítése

Az SDK-ban szereplő összes válasznak ,beleértve CosmosExceptiona tulajdonságát Diagnostics is. Ez a tulajdonság az egyetlen kéréssel kapcsolatos összes információt rögzíti, beleértve azt is, hogy voltak-e újrapróbálkozások vagy átmeneti hibák.

A diagnosztika sztringként lesz visszaadva. A sztring az egyes verziókkal változik, mivel javult a különböző forgatókönyvek hibaelhárításához. Az SDK minden egyes verziójánál a sztring formázása töredezett lesz. Ne elemezd a sztringet a módosítások megszakításának elkerülése érdekében. Az alábbi kódminta bemutatja, hogyan olvashatja be a diagnosztikai naplókat a .NET SDK használatával:

try
{
    ItemResponse<Book> response = await this.Container.CreateItemAsync<Book>(item: testItem);
    if (response.Diagnostics.GetClientElapsedTime() > ConfigurableSlowRequestTimeSpan)
    {
        // Log the response.Diagnostics.ToString() and add any additional info necessary to correlate to other logs 
    }
}
catch (CosmosException cosmosException)
{
    // Log the full exception including the stack trace with: cosmosException.ToString()
    
    // The Diagnostics can be logged separately if required with: cosmosException.Diagnostics.ToString()
}

// When using Stream APIs
ResponseMessage response = await this.Container.CreateItemStreamAsync(partitionKey, stream);
if (response.Diagnostics.GetClientElapsedTime() > ConfigurableSlowRequestTimeSpan || !response.IsSuccessStatusCode)
{
    // Log the diagnostics and add any additional info necessary to correlate to other logs with: response.Diagnostics.ToString()
}

Diagnosztika a 3.19-es és újabb verzióban

A JSON-struktúra kompatibilitástörő változásokat eredményez az SDK minden verziójában. Ez nem biztonságossá teszi az elemzést. A JSON a kérelem SDK-n keresztüli faszerkezetét jelöli. Az alábbi szakaszok néhány fontos szempontot mutatnak be.

Processzorelőzmények

A lassú kérések leggyakoribb oka a magas processzorhasználat. Az optimális késéshez a processzorkihasználtságnak nagyjából 40 százalékosnak kell lennie. A maximális (nem átlagos) processzorkihasználtságot 10 másodperces időközönként monitorozza. A cpu-kiugrások gyakoribbak a partíciók közötti lekérdezéseknél, ahol a kérések több kapcsolatot is futtathatnak egyetlen lekérdezéshez.

Az időtúllépések közé tartoznak a diagnosztikák, amelyek például a következőket tartalmazzák:

"systemHistory": [
{
"dateUtc": "2021-11-17T23:38:28.3115496Z",
"cpu": 16.731,
"memory": 9024120.000,
"threadInfo": {
"isThreadStarving": "False",
....
}

},
{
"dateUtc": "2021-11-17T23:38:38.3115496Z",
"cpu": 16.731,
"memory": 9024120.000,
"threadInfo": {
"isThreadStarving": "False",
....
}

},
...
]
  • Ha az cpu értékek több mint 70%-osak, az időtúllépést valószínűleg a processzor elfogyása okozza. Ebben az esetben a megoldás a magas CPU-kihasználtság forrásának vizsgálata és a kihasználtság csökkentése, vagy a gép felskálázása egy nagyobb erőforrás-méretre.
  • Ha a threadInfo/isThreadStarving csomópontok értékei vannak True , az ok a szál éhezése. Ebben az esetben a megoldás a szál éhezésének (esetleg zárolt szálak) forrásának vagy forrásainak vizsgálata, vagy a gép vagy gépek nagyobb erőforrásméretre skálázása.
  • Ha a dateUtc mérések közötti idő nem körülbelül 10 másodperc, az a szálkészlet versengését is jelzi. A cpu független feladatként van mérve, amely 10 másodpercenként van leküldve a szálkészletben. Ha a mérések közötti idő hosszabb, az azt jelzi, hogy az aszinkron feladatok nem dolgozhatók fel időben. A leggyakoribb forgatókönyv az, amikor az alkalmazáskód blokkolja az aszinkron kódon keresztüli hívásokat.

Megoldás

Az SDK-t használó ügyfélalkalmazást horizontálisan vagy vertikálisan fel kell skálázni.

HttpResponseStats

HttpResponseStats az átjáróra irányuló kérések. Az SDK még közvetlen módban is lekéri az átjáró összes metaadat-információját.

Ha a kérés lassú, először ellenőrizze, hogy az előző javaslatok egyike sem adja-e meg a kívánt eredményt. Ha még mindig lassú, a különböző minták különböző problémákra mutatnak. Az alábbi táblázat további részleteket tartalmaz.

Kérelmek száma Forgatókönyv Leírás
Egy az összeshez Kérés időtúllépése vagy HttpRequestExceptions Az SNAT-port elfogyására utal, vagy arra, hogy nincs elegendő erőforrás a gépen a kérés időben történő feldolgozásához.
Egy vagy kis százalék (az SLA nem sérül) Mind A lassú kérések egy vagy kis százalékát számos átmeneti probléma okozhatja, és várható.
Mind Mind Az infrastruktúrával vagy hálózatkezeléssel kapcsolatos problémára mutat.
SLA megsértve Az alkalmazás nem módosult, és az SLA elvetve. Az Azure Cosmos DB szolgáltatással kapcsolatos problémára mutat.
"HttpResponseStats": [
    {
        "StartTimeUTC": "2021-06-15T13:53:09.7961124Z",
        "EndTimeUTC": "2021-06-15T13:53:09.7961127Z",
        "RequestUri": "https://127.0.0.1:8081/dbs/347a8e44-a550-493e-88ee-29a19c070ecc/colls/4f72e752-fa91-455a-82c1-bf253a5a3c4e",
        "ResourceType": "Collection",
        "HttpMethod": "GET",
        "ActivityId": "e16e98ec-f2e3-430c-b9e9-7d99e58a4f72",
        "StatusCode": "OK"
    }
]

StoreResult

StoreResult egyetlen kérést jelöl az Azure Cosmos DB-nek közvetlen mód használatával a TCP protokollal.

Ha még mindig lassú, a különböző minták különböző problémákra mutatnak. Az alábbi táblázat további részleteket tartalmaz.

Kérelmek száma Forgatókönyv Leírás
Egy az összeshez StoreResult Tartalmaz TransportException Az SNAT-portok elfogyására vagy a kérés időben történő feldolgozásához szükséges erőforrások hiányára utal.
Egy vagy kis százalék (az SLA nem sérül) Mind A lassú kérések egy vagy kis százalékát számos különböző átmeneti probléma okozhatja, és ez várható.
Mind Mind Az infrastruktúrával vagy a hálózattal kapcsolatos probléma.
SLA megsértve A kérések több hibakódot tartalmaznak, például 410 Az Azure Cosmos DB szolgáltatással vagy az ügyfélszámítógéppel kapcsolatos problémára mutat.
SLA megsértve StorePhysicalAddress azonosak, hibaállapotkód nélkül. Valószínűleg probléma merült fel az Azure Cosmos DB-vel kapcsolatban.
SLA megsértve StorePhysicalAddress ugyanazzal a partícióazonosítóval, de különböző replikaazonosítókkal rendelkezik, hibaállapotkód nélkül. Valószínűleg probléma merült fel az Azure Cosmos DB-vel kapcsolatban.
SLA megsértve StorePhysicalAddress véletlenszerű, hibaállapotkód nélkül. A géppel kapcsolatos problémára mutat.

Egyetlen kérelem több áruházbeli eredményéhez vegye figyelembe a következőket:

  • Az erős konzisztencia és a korlátozott frissesség konzisztencia mindig legalább két tárolási eredménnyel rendelkezik.
  • Ellenőrizze az egyes StoreResultállapotkódokat. Az SDK automatikusan újrapróbálkozott több különböző átmeneti hibával. Az SDK-t folyamatosan fejlesztik, hogy több forgatókönyvet is lefedjenek.

RequestTimeline

A kérések átviteli rétegben való küldésének és fogadásának különböző fázisainak idejét jeleníti meg.

  • ChannelAcquisitionStarted: Az új kapcsolat beszerzésének vagy létrehozásának ideje. A kapcsolatok számos okból hozhatók létre, például: Az előző kapcsolat megszakadt a CosmosClientOptions.IdleTcpConnectionTimeout inaktivitása miatt, az egyidejű kérések mennyisége meghaladja a CosmosClientOptions.MaxRequestsPerTcpConnection értéket, a kapcsolat hálózati hiba miatt megszakadt, vagy az alkalmazás nem követi a Singleton-mintát , és folyamatosan új példányok jönnek létre. A kapcsolat létrejötte után a rendszer újra felhasználja a későbbi kérésekhez, így ez nem befolyásolhatja a P99 késését, hacsak a korábban említett problémák nem fordulnak elő.
  • Pipelined az idő nagy lehet, amelyet egy nagy kérés okozhat.
  • Transit time nagy méretű, ami hálózati problémához vezet. Hasonlítsa össze ezt a számot a számmal BELatencyInMs. Ha BELatencyInMs kicsi, akkor az időt a hálózaton, nem pedig az Azure Cosmos DB szolgáltatásban töltötték.
  • Received A hosszú időt egy szál éhezési problémája okozhatja. Ez a válasz és az eredmény visszaadása közötti idő.

ServiceEndpointStatistics

Információ egy adott háttérkiszolgálóról. Az SDK több kapcsolatot is megnyithat egyetlen háttérkiszolgálón a függőben lévő kérések számától és a MaxConcurrentRequestsPerConnectiontól függően.

  • inflightRequests A háttérkiszolgálóra irányuló függőben lévő kérések száma (esetleg különböző partíciókról). A magas szám nagyobb forgalomhoz és nagyobb késéshez vezethet.
  • openConnections az egyetlen háttérkiszolgálóhoz megnyitott kapcsolatok teljes száma. Ez hasznos lehet az SNAT-portok kimerülésének szemléltetésére, ha ez a szám nagyon magas.

ConnectionStatistics

Információ arról a kapcsolatról (új vagy régi), amelyhez a kérés hozzá van rendelve.

  • waitforConnectionInit: Az aktuális kérés az új kapcsolati inicializálás befejezésére várt. Ez magasabb késésekhez vezet.
  • callsPendingReceive: A hívás elküldése előtt függőben lévő hívások száma. Egy magas szám azt mutathatja, hogy sok hívás volt a hívás előtt, és ez magasabb késésekhez vezethet. Ha ez a szám magas, az egy sorblokkolási problémára utal, amelyet esetleg egy másik kérés, például egy lekérdezési vagy adatcsatorna-művelet okoz, amely hosszú ideig tart a feldolgozás során. Próbálja meg csökkenteni a CosmosClientOptions.MaxRequestsPerTcpConnection elemet a csatornák számának növeléséhez.
  • LastSentTime: A kiszolgálónak küldött utolsó kérés időpontja. Ez a LastReceivedTime-val együtt használható a csatlakozási vagy végponti problémák megtekintéséhez. Ha például sok a fogadási időtúllépés, az elküldött idő sokkal nagyobb lesz, mint a fogadási idő.
  • lastReceive: A kiszolgálótól kapott utolsó kérés időpontja
  • lastSendAttempt: Az utolsó küldési kísérlet időpontja

Kérelem- és válaszméretek

  • requestSizeInBytes: Az Azure Cosmos DB-nek küldött kérés teljes mérete
  • responseMetadataSizeInBytes: Az Azure Cosmos DB-ből visszaadott fejlécek mérete
  • responseBodySizeInBytes: Az Azure Cosmos DB-ből visszaadott tartalom mérete
"StoreResult": {
    "ActivityId": "bab6ade1-b8de-407f-b89d-fa2138a91284",
    "StatusCode": "Ok",
    "SubStatusCode": "Unknown",
    "LSN": 453362,
    "PartitionKeyRangeId": "1",
    "GlobalCommittedLSN": 0,
    "ItemLSN": 453358,
    "UsingLocalLSN": true,
    "QuorumAckedLSN": -1,
    "SessionToken": "-1#453362",
    "CurrentWriteQuorum": -1,
    "CurrentReplicaSetSize": -1,
    "NumberOfReadRegions": 0,
    "IsValid": true,
    "StorePhysicalAddress": "rntbd://127.0.0.1:10253/apps/DocDbApp/services/DocDbServer92/partitions/a4cb49a8-38c8-11e6-8106-8cdcd42c33be/replicas/1s/",
    "RequestCharge": 1,
    "RetryAfterInMs": null,
    "BELatencyInMs": "0.304",
    "transportRequestTimeline": {
        "requestTimeline": [
            {
                "event": "Created",
                "startTimeUtc": "2022-05-25T12:03:36.3081190Z",
                "durationInMs": 0.0024
            },
            {
                "event": "ChannelAcquisitionStarted",
                "startTimeUtc": "2022-05-25T12:03:36.3081214Z",
                "durationInMs": 0.0132
            },
            {
                "event": "Pipelined",
                "startTimeUtc": "2022-05-25T12:03:36.3081346Z",
                "durationInMs": 0.0865
            },
            {
                "event": "Transit Time",
                "startTimeUtc": "2022-05-25T12:03:36.3082211Z",
                "durationInMs": 1.3324
            },
            {
                "event": "Received",
                "startTimeUtc": "2022-05-25T12:03:36.3095535Z",
                "durationInMs": 12.6128
            },
            {
                "event": "Completed",
                "startTimeUtc": "2022-05-25T12:03:36.8621663Z",
                "durationInMs": 0
            }
        ],
        "serviceEndpointStats": {
            "inflightRequests": 1,
            "openConnections": 1
        },
        "connectionStats": {
            "waitforConnectionInit": "False",
            "callsPendingReceive": 0,
            "lastSendAttempt": "2022-05-25T12:03:34.0222760Z",
            "lastSend": "2022-05-25T12:03:34.0223280Z",
            "lastReceive": "2022-05-25T12:03:34.0257728Z"
        },
        "requestSizeInBytes": 447,
        "responseMetadataSizeInBytes": 438,
        "responseBodySizeInBytes": 604
    },
    "TransportException": null
}

A hibaarány sérti az Azure Cosmos DB SLA-t

Lépjen kapcsolatba Azure-támogatás.

Következő lépések