Delen via


Trage aanvragen vaststellen en oplossen in Azure Cosmos DB .NET SDK

VAN TOEPASSING OP: NoSQL

In Azure Cosmos DB ziet u mogelijk trage aanvragen. Vertragingen kunnen om meerdere redenen optreden, zoals aanvraagbeperking of de manier waarop uw toepassing is ontworpen. In dit artikel worden de verschillende hoofdoorzaken voor dit probleem uitgelegd.

Aanvraagsnelheid is te hoog

Aanvraagbeperking is de meest voorkomende reden voor trage aanvragen. Azure Cosmos DB beperkt aanvragen als ze de toegewezen aanvraageenheden voor de database of container overschrijden. De SDK heeft ingebouwde logica om deze aanvragen opnieuw uit te voeren. In het artikel voor het oplossen van problemen met de aanvraagsnelheid wordt uitgelegd hoe u kunt controleren of de aanvragen worden beperkt. In het artikel wordt ook besproken hoe u uw account kunt schalen om deze problemen in de toekomst te voorkomen.

Toepassingsontwerp

Wanneer u uw toepassing ontwerpt, volgt u de best practices voor .NET SDK voor de beste prestaties. Als uw toepassing niet de best practices voor de SDK volgt, krijgt u mogelijk trage of mislukte aanvragen.

Houd rekening met het volgende bij het ontwikkelen van uw toepassing:

Metagegevensbewerkingen

Als u wilt controleren of er een database of container bestaat, doet u dit niet door een itembewerking aan te roepen Create...IfNotExistsAsync of Read...Async voordat u een itembewerking uitvoert. De validatie moet alleen worden uitgevoerd bij het opstarten van de toepassing wanneer dit nodig is, als u verwacht dat ze worden verwijderd. Deze metagegevensbewerkingen genereren extra latentie, hebben geen SLA (Service Level Agreement) en hebben hun eigen afzonderlijke beperkingen. Ze worden niet geschaald, zoals gegevensbewerkingen.

Trage aanvragen in bulkmodus

Bulkmodus is een modus die is geoptimaliseerd voor doorvoer, bedoeld voor bewerkingen met een hoog gegevensvolume, niet voor latentie geoptimaliseerde modus. Deze modus is bedoeld om de beschikbare doorvoer te verzadigen. Als u trage aanvragen ondervindt bij het gebruik van de bulkmodus, controleert u of:

  • Uw toepassing wordt gecompileerd in de releaseconfiguratie.
  • U meet geen latentie tijdens het opsporen van fouten in de toepassing (er zijn geen foutopsporingsprogramma's gekoppeld).
  • Het volume van bewerkingen is hoog, gebruik geen bulk voor minder dan 1000 bewerkingen. De ingerichte doorvoer bepaalt hoeveel bewerkingen per seconde u kunt verwerken. Het doel van bulksgewijs is om zoveel mogelijk bewerkingen te gebruiken.
  • Bewaak de container voor beperkingsscenario's. Als de container zwaar wordt beperkt, betekent dit dat het gegevensvolume groter is dan de ingerichte doorvoer, moet u de container omhoog schalen of het volume van gegevens verminderen (misschien kleinere batches met gegevens tegelijk maken).
  • U gebruikt het async/await patroon correct om alle gelijktijdige taken te verwerken en geen asynchrone bewerkingen te blokkeren.

Diagnostische gegevens vastleggen

Alle antwoorden in de SDK, inclusief CosmosException, hebben een Diagnostics eigenschap. Deze eigenschap registreert alle informatie met betrekking tot de enkele aanvraag, inclusief of er nieuwe pogingen of tijdelijke fouten zijn opgetreden.

De diagnostische gegevens worden geretourneerd als een tekenreeks. De tekenreeks verandert met elke versie, omdat deze is verbeterd voor het oplossen van problemen met verschillende scenario's. Bij elke versie van de SDK heeft de tekenreeks belangrijke wijzigingen in de opmaak. Parseert de tekenreeks niet om wijzigingen die fouten veroorzaken te voorkomen. In het volgende codevoorbeeld ziet u hoe u diagnostische logboeken leest met behulp van de .NET SDK:

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

Diagnostische gegevens in versie 3.19 en hoger

De JSON-structuur heeft belangrijke wijzigingen met elke versie van de SDK. Dit maakt het onveilig om te worden geparseerd. De JSON vertegenwoordigt een structuurstructuur van de aanvraag die via de SDK gaat. In de volgende secties worden enkele belangrijke zaken besproken die u moet bekijken.

CPU-geschiedenis

Hoog CPU-gebruik is de meest voorkomende oorzaak voor trage aanvragen. Voor een optimale latentie moet het CPU-gebruik ongeveer veertig procent zijn. Gebruik 10 seconden als interval om het maximale (niet het gemiddelde) CPU-gebruik te bewaken. CPU-pieken komen vaker voor bij query's tussen partities, waarbij de aanvragen mogelijk meerdere verbindingen uitvoeren voor één query.

De time-outs bevatten diagnostische gegevens, die bijvoorbeeld het volgende bevatten:

"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",
....
}

},
...
]
  • Als de cpu waarden hoger zijn dan 70 procent, wordt de time-out waarschijnlijk veroorzaakt door CPU-uitputting. In dit geval kunt u de bron voor het hoge CPU-gebruik onderzoeken en deze verminderen, of de computer opschalen voor gebruik van grotere resources.
  • Als de threadInfo/isThreadStarving knooppunten waarden hebben True , is de oorzaak thread-starvatie. In dit geval is de oplossing het onderzoeken van de bron of bronnen van de thread-honger (mogelijk vergrendelde threads) of het schalen van de machine of machines naar een grotere resourcegrootte.
  • Als de dateUtc tijd tussen metingen niet ongeveer 10 seconden is, geeft dit ook conflicten aan in de threadpool. CPU wordt elke 10 seconden gemeten als een onafhankelijke taak die in de threadpool wordt uitgevoerd. Als de tijd tussen metingen langer is, geeft dit aan dat de asynchrone taken niet tijdig kunnen worden verwerkt. Het meest voorkomende scenario is wanneer uw toepassingscode aanroepen blokkeert via asynchrone code.

Oplossing

De clienttoepassing die gebruikmaakt van de SDK, moet dan omhoog of omlaag worden geschaald.

HttpResponseStats

HttpResponseStats zijn aanvragen die naar de gateway gaan. Zelfs in de directe modus haalt de SDK alle metagegevensgegevens van de gateway op.

Als de aanvraag traag is, controleert u eerst of geen van de vorige suggesties de gewenste resultaten oplevert. Als het nog steeds traag is, wijzen verschillende patronen op verschillende problemen. De volgende tabel bevat meer informatie.

Aantal aanvragen Scenario Beschrijving
Eén-op-alles Time-out van aanvraag of HttpRequestExceptions Verwijst naar SNAT-poortuitputting of een gebrek aan resources op de computer om de aanvraag tijdig te verwerken.
Eén of klein percentage (SLA wordt niet geschonden) Alle Een of klein percentage trage aanvragen kan worden veroorzaakt door verschillende tijdelijke problemen en moet worden verwacht.
Alle Alle Verwijst naar een probleem met de infrastructuur of netwerken.
SLA is geschonden Er zijn geen wijzigingen in de toepassing en sla verwijderd. Verwijst naar een probleem met de Azure Cosmos DB-service.
"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 vertegenwoordigt één aanvraag naar Azure Cosmos DB met behulp van de directe modus met het TCP-protocol.

Als het nog steeds traag is, wijzen verschillende patronen op verschillende problemen. De volgende tabel bevat meer informatie.

Aantal aanvragen Scenario Beschrijving
Eén-op-alles StoreResult Bevat TransportException Verwijst naar SNAT-poortuitputting of een gebrek aan resources op de computer om de aanvraag tijdig te verwerken.
Eén of klein percentage (SLA wordt niet geschonden) Alle Een of klein percentage trage aanvragen kan worden veroorzaakt door verschillende tijdelijke problemen en moet worden verwacht.
Alle Alle Een probleem met de infrastructuur of netwerken.
SLA is geschonden Aanvragen bevatten meerdere foutcodes, zoals 410 Verwijst naar een probleem met de Azure Cosmos DB-service of de clientcomputer.
SLA is geschonden StorePhysicalAddress zijn hetzelfde, zonder foutcode. Waarschijnlijk een probleem met Azure Cosmos DB.
SLA is geschonden StorePhysicalAddress dezelfde partitie-id hebben, maar verschillende replica-id's, zonder foutcode. Waarschijnlijk een probleem met Azure Cosmos DB.
SLA is geschonden StorePhysicalAddress is willekeurig, zonder foutcode. Verwijst naar een probleem met de machine.

Houd rekening met het volgende voor meerdere winkelresultaten voor één aanvraag:

  • Sterke consistentie en gebonden verouderingsconsistentie hebben altijd ten minste twee winkelresultaten.
  • Controleer de statuscode van elke StoreResult. De SDK probeert automatisch opnieuw op meerdere tijdelijke fouten. De SDK is voortdurend verbeterd om meer scenario's te behandelen.

RequestTimeline

De tijd weergeven voor de verschillende fasen van het verzenden en ontvangen van een aanvraag in de transportlaag.

  • ChannelAcquisitionStarted: de tijd voor het ophalen of maken van een nieuwe verbinding. Verbindingen kunnen om verschillende redenen worden gemaakt, zoals: De vorige verbinding is gesloten vanwege inactiviteit met cosmosClientOptions.IdleTcpConnectionTimeout, het volume van gelijktijdige aanvragen overschrijdt de CosmosClientOptions.MaxRequestsPerTcpConnection, de verbinding is gesloten vanwege een netwerkfout, of de toepassing volgt het Singleton-patroon niet en nieuwe exemplaren worden voortdurend gemaakt. Zodra er een verbinding tot stand is gebracht, wordt deze opnieuw gebruikt voor volgende aanvragen. Dit heeft dus geen invloed op de P99-latentie, tenzij de eerder genoemde problemen zich voordoen.
  • Pipelined: De tijd die is besteed aan het schrijven van de aanvraag in de TCP-socket. Een aanvraag kan slechts één voor één worden geschreven op een TCP-socket. Een grote waarde geeft een knelpunt aan in de TCP-socket die vaak is gekoppeld aan vergrendelde threads door de toepassingscode of de grootte van grote aanvragen.
  • Transit time: De tijd die is besteed aan het netwerk nadat de aanvraag is geschreven op de TCP-socket. Vergelijk dit getal met de BELatencyInMs. Als BELatencyInMs dit klein is, is de tijd besteed aan het netwerk en niet in de Azure Cosmos DB-service. Als de aanvraag is mislukt met een time-out, wordt aangegeven hoe lang de client zonder reactie heeft gewacht en de bron netwerklatentie is.
  • Received: De tijd tussen het antwoord is ontvangen en verwerkt door de SDK. Een grote waarde wordt normaal gesproken veroorzaakt door een threadsteratie of vergrendelde threads.

ServiceEndpointStatistics

Informatie over een bepaalde back-endserver. De SDK kan meerdere verbindingen met één back-endserver openen, afhankelijk van het aantal aanvragen in behandeling en de MaxConcurrentRequestsPerConnection.

  • inflightRequests Het aantal aanvragen dat in behandeling is op een back-endserver (mogelijk van verschillende partities). Een hoog aantal kan leiden tot meer verkeer en hogere latenties.
  • openConnections is het totale aantal verbindingen dat is geopend met één back-endserver. Dit kan handig zijn om SNAT-poortuitputting weer te geven als dit aantal zeer hoog is.

ConnectionStatistics

Informatie over de specifieke verbinding (nieuw of oud) waaraan de aanvraag wordt toegewezen.

  • waitforConnectionInit: De huidige aanvraag wachtte totdat de initialisatie van de nieuwe verbinding is voltooid. Dit leidt tot hogere latenties.
  • callsPendingReceive: Aantal oproepen dat in behandeling was voordat deze oproep werd verzonden. Een hoog nummer kan ons laten zien dat er veel oproepen vóór deze oproep waren en dat dit kan leiden tot hogere latenties. Als dit aantal hoog is, verwijst het naar een probleem met het blokkeren van lijnen dat mogelijk wordt veroorzaakt door een andere aanvraag, zoals een query of feedbewerking die lang duurt om te verwerken. Probeer cosmosClientOptions.MaxRequestsPerTcpConnection te verlagen om het aantal kanalen te verhogen.
  • LastSentTime: Het tijdstip van de laatste aanvraag die naar deze server is verzonden. Dit samen met LastReceivedTime kan worden gebruikt om verbindingsproblemen of eindpuntproblemen te bekijken. Als er bijvoorbeeld veel time-outs voor ontvangst zijn, is verzonden tijd veel groter dan de ontvangsttijd.
  • lastReceive: Tijdstip van laatste aanvraag die is ontvangen van deze server
  • lastSendAttempt: Tijd van de laatste verzendpoging

Aanvraag- en antwoordgrootten

  • requestSizeInBytes: De totale grootte van de aanvraag die naar Azure Cosmos DB is verzonden
  • responseMetadataSizeInBytes: De grootte van headers die worden geretourneerd uit Azure Cosmos DB
  • responseBodySizeInBytes: De grootte van inhoud die wordt geretourneerd vanuit Azure Cosmos DB
"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
}

Foutpercentage schendt de SLA van Azure Cosmos DB

Neem contact op met ondersteuning voor Azure.

Volgende stappen