Metodtips för Azure Cosmos DB .NET SDK

GÄLLER FÖR: NoSQL

Den här artikeln går igenom metodtipsen för att använda Azure Cosmos DB .NET SDK. Genom att följa dessa metoder kan du förbättra svarstiden, tillgängligheten och öka den övergripande prestandan.

Titta på följande video om du vill veta mer om hur du använder .NET SDK från en Azure Cosmos DB-tekniker!

Checklista

Kryssruta Ämne Beskrivning
SDK-version Använd alltid den senaste versionen av Azure Cosmos DB SDK som är tillgänglig för optimala prestanda.
Singleton-klient Använd en enda instans av CosmosClient under programmets livslängd för bättre prestanda.
Regioner Se till att köra ditt program i samma Azure-region som ditt Azure Cosmos DB-konto när det är möjligt för att minska svarstiden. Aktivera 2–4 regioner och replikera dina konton i flera regioner för bästa tillgänglighet. För produktionsarbetsbelastningar, aktivera tjänsthanterad redundans. I avsaknad av den här konfigurationen upplever kontot förlust av skrivtillgänglighet under hela avbrottstiden för skrivregionen, eftersom manuell redundans inte lyckas på grund av brist på regionanslutning. Mer information om hur du lägger till flera regioner med hjälp av .NET SDK finns i den här självstudien.
Tillgänglighet och redundans Ange ApplicationPreferredRegions eller ApplicationRegion i v3 SDK och PreferredLocations i v2 SDK med hjälp av listan med önskade regioner. Under failoverhändelser skickas skrivåtgärder till den nuvarande skrivregionen och alla läsåtgärder skickas till den första regionen i listan över önskade regioner. Mer information om regionala failovermekanismer finns i felsökningsguiden för tillgänglighet.
Processor Du kan stöta på anslutning/tillgänglighetsproblem på grund av brist på resurser på klientdatorn. Övervaka cpu-användningen på noder som kör Azure Cosmos DB-klienten och skala upp/ut om användningen är hög.
Webbhosting Använd Windows 64-bitars värdbearbetning för bästa prestanda när det är möjligt. För fördröjningskänsliga produktionsarbetsbelastningar i direktläge rekommenderar vi starkt att du använder minst 4 kärnor och virtuella datorer med 8 GB minne när det är möjligt.
Anslutningslägen Använd direktläge för bästa prestanda. Anvisningar finns i V3 SDK-dokumentationen eller V2 SDK-dokumentationen.
Nätverk Om du använder en virtuell dator för att köra programmet aktiverar du Accelererat nätverk på den virtuella datorn för att hjälpa till med flaskhalsar på grund av hög trafik och minska svarstiden eller CPU-jitter. Du kanske också vill överväga att använda en virtuell dator med högre slutpunkt där den maximala CPU-användningen är under 70%.
Tillfällig portöverbelastning För glesa eller sporadiska anslutningar ställer vi IdleConnectionTimeout och PortReuseMode till PrivatePortPool. Egenskapen IdleConnectionTimeout hjälper till att kontrollera den tid efter vilken oanvända anslutningar stängs. Detta minskar antalet oanvända anslutningar. Som standard hålls inaktiva anslutningar öppna på obestämd tid. Värdeuppsättningen måste vara större än eller lika med 10 minuter. Vi rekommenderar värden mellan 20 minuter och 24 timmar. Med PortReuseMode egenskapen kan SDK:n använda en liten pool med tillfälliga portar för olika Azure Cosmos DB-målslutpunkter.
Använd async/await Undvik blockeringsanrop: Task.Result, Task.Waitoch Task.GetAwaiter().GetResult(). Hela anropsstacken är asynkron för att dra nytta av asynkrona/väntande mönster. Många synkrona blockeringsanrop leder till utsvulten trådpool och försämrade svarstider.
Tidsgränser från slutpunkt till slutpunkt För att få ända-till-ända timeouter behöver du använda både RequestTimeout och CancellationToken parametrar. Mer information finns i vår felsökningsguide för timeout.
Logik för återförsök Mer information om vilka fel som ska försöka igen och vilka som görs om av SDK:er finns i designguiden. För konton som har konfigurerats med flera regioner finns det vissa scenarier där SDK:t automatiskt försöker igen i andra regioner. För. NET-specifik implementeringsinformation finns i SDK-källlagringsplatsen.
Cachelagring av databas-/samlingsnamn Hämta namnen på dina databaser och containrar från konfigurationen eller cachelagrar dem vid start. Anrop som ReadDatabaseAsync eller ReadDocumentCollectionAsync och CreateDatabaseQuery eller CreateDocumentCollectionQuery resulterar i metadataanrop till tjänsten, som förbrukar från den systemreserverade RU-gränsen. CreateIfNotExist bör också endast användas en gång för att konfigurera databasen. Sammantaget bör dessa åtgärder utföras sällan.
Massstöd I scenarier där du kanske inte behöver optimera för svarstid rekommenderar vi att du aktiverar massstöd för dumpning av stora mängder data.
Parallella frågor Azure Cosmos DB SDK stöder körning av frågor parallellt för bättre svarstid och dataflöde på dina frågor. Vi rekommenderar att du anger MaxConcurrency egenskapen inom QueryRequestsOptions det antal partitioner som du har. Om du inte känner till antalet partitioner börjar du med att använda int.MaxValue, vilket ger dig den bästa svarstiden. Minska sedan antalet tills det passar resursbegränsningarna i miljön för att undvika höga CPU-problem. Ange MaxBufferedItemCount också till det förväntade antalet resultat som returneras för att begränsa antalet fördefinierade resultat.
Backoffs för prestandatestning När du utför testning i ditt program bör du implementera backoffs med RetryAfter jämna mellanrum. Om du respekterar väntetiden ser du till att du tillbringar så lite tid som möjligt med att vänta mellan återförsöken.
Indexering Med Azure Cosmos DB-indexeringsprincipen kan du också ange vilka dokumentsökvägar som ska inkluderas eller undantas från indexering med hjälp av indexeringssökvägar (IndexingPolicy.IncludedPaths och IndexingPolicy.ExcludedPaths). Se till att du undantar oanvända sökvägar från indexering för snabbare skrivningar. Mer information om hur du skapar index med hjälp av SDK finns i Indexeringsprincip.
Dokumentstorlek Begärandeavgiften för en angiven åtgärd korrelerar direkt med dokumentets storlek. Vi rekommenderar att du minskar storleken på dina dokument eftersom åtgärder på stora dokument kostar mer än åtgärder på mindre dokument.
Öka antalet trådar/uppgifter Eftersom anrop till Azure Cosmos DB görs via nätverket kan du behöva variera graden av samtidighet för dina begäranden så att klientprogrammet ägnar minimal tid åt att vänta mellan begäranden. Om du till exempel använder .NET-aktivitetsparallellt bibliotek skapar du i ordningen hundratals aktiviteter som läser från eller skriver till Azure Cosmos DB.
Aktivera frågemått För mer loggning av dina backendfrågeexekveringar kan du aktivera SQL Query Metrics med hjälp av vår .NET SDK. Mer information om hur du samlar in SQL-frågemått finns i frågemått och prestanda.
SDK-loggning Logga SDK-diagnostik för särskilda scenarier, till exempel undantag eller när begäranden överskrider en förväntad latens.
DefaultTraceListener Innebär DefaultTraceListener prestandaproblem i produktionsmiljöer som orsakar hög CPU-belastning och I/O-flaskhalsar. Kontrollera att du använder de senaste SDK-versionerna eller ta bort DefaultTraceListener från ditt program.
Undvik att använda specialtecken i identifierare Vissa tecken är begränsade och kan inte användas i vissa identifierare: /, \, ?, #. Den allmänna rekommendationen är att inte använda några specialtecken i identifierare som databasnamn, samlingsnamn, objekt-ID eller partitionsnyckel för att undvika oväntade beteenden.

Hantera Newtonsoft.Json-beroenden

Översikt

Azure Cosmos DB .NET SDK är beroende av Newtonsoft.Json för JSON-serialiseringsfunktioner. Det här beroendet hanteras inte automatiskt – du måste uttryckligen lägga till Newtonsoft.Json som ett direkt beroende i projektet.

SDK:n kompileras mot Newtonsoft.Json 10.x internt, som har en känd säkerhetsrisk. Även om SDK:n är tekniskt kompatibel med 10.x och SDK:ns användning av Newtonsoft.Json inte är mottaglig för det rapporterade säkerhetsproblemet rekommenderar vi fortfarande att du använder version 13.0.3 eller senare för att undvika potentiella säkerhetsproblem eller konflikter. 13.x-versionerna innehåller icke-bakåtkompatibla ändringar, men SDK:ets användningsmönster är kompatibla med dessa ändringar.

Viktigt!

Det här beroendet krävs även när du använder System.Text.Json för användardefinierade typer via CosmosClientOptions.UseSystemTextJsonSerializerWithOptions, eftersom SDK:ns interna åtgärder fortfarande använder Newtonsoft.Json för systemtyper.

Lägg alltid uttryckligen till Newtonsoft.Json version 13.0.3 eller senare som ett direkt beroende när du använder Azure Cosmos DB .NET SDK v3. Använd inte version 10.x på grund av kända säkerhetsrisker.

För standard .csproj-projekt

<ItemGroup>
  <PackageReference Include="Microsoft.Azure.Cosmos" Version="3.47.0" />
  <PackageReference Include="Newtonsoft.Json" Version="13.0.4" />
</ItemGroup>

För projekt med central pakethantering

Om projektet använder Directory.Packages.props:

<Project>
  <ItemGroup>
    <PackageVersion Include="Microsoft.Azure.Cosmos" Version="3.47.0" />
    <PackageVersion Include="Newtonsoft.Json" Version="13.0.4" />
  </ItemGroup>
</Project>

Felsöka versionskonflikter

Newtonsoft.Json-referens saknas

Om du stöter på ett byggfel som:

The Newtonsoft.Json package must be explicitly referenced with version >= 10.0.2. Please add a reference to Newtonsoft.Json or set the 'AzureCosmosDisableNewtonsoftJsonCheck' property to 'true' to bypass this check.

Det här felet genereras avsiktligt av Cosmos DB SDK:s byggmål för att säkerställa att beroendet är korrekt konfigurerat.

Lösning för program:

Lägg till en explicit referens till Newtonsoft.Json som du ser i avsnittet Rekommenderad konfiguration ovan.

Lösning för bibliotek:

Om du skapar ett bibliotek (inte ett program) och vill skjuta upp Newtonsoft.Json-beroendet till bibliotekets konsumenter kan du kringgå den här kontrollen genom att ange egenskapen MSBuild i :.csproj

<PropertyGroup>
  <AzureCosmosDisableNewtonsoftJsonCheck>true</AzureCosmosDisableNewtonsoftJsonCheck>
</PropertyGroup>

Varning

Använd endast den här förbikopplingen när du skapar bibliotek där slutanvändarna tillhandahåller Newtonsoft.Json-beroendet. För applikationer lägger du alltid till den tydliga referensen.

Paketversionskonflikter

Om du stöter på byggfel som:

error NU1109: Detected package downgrade: Newtonsoft.Json from 13.0.4 to centrally defined 13.0.3

Solution:

  1. Identifiera den version som krävs genom att kontrollera vilka paket som behöver nyare versioner:

    dotnet list package --include-transitive | Select-String "Newtonsoft.Json"
    
  2. Uppdatera din centraliserade paketversion så att den matchar eller överskrider den version som krävs högst:

    <PackageVersion Include="Newtonsoft.Json" Version="13.0.4" />
    
  3. Rensa och återskapa:

    dotnet clean
    dotnet restore
    dotnet build
    

Versionskompatibilitet

I följande tabell visas de lägsta rekommenderade säkra versionerna av Newtonsoft.Json för varje Cosmos DB SDK-version. Även om SDK:et tekniskt sett kan fungera med 10.x bör dessa versioner aldrig användas på grund av säkerhetsrisker.

Cosmos DB SDK-version Lägsta säkra version Rekommenderat
3.47.0+ 13.0.3 13.0.4
3.54.0+ 13.0.4 13.0.4

Tips/Råd

När du använder .NET Aspire 13.0.0 eller senare kontrollerar du Newtonsoft.Json att version 13.0.4 är på för att undvika konflikter med Aspires Azure-komponenter.

Metodtips

  • Lägg alltid till som ett direkt beroende – SDK hanterar inte det här beroendet automatiskt åt dig
  • Använd version 13.0.3 eller senare – Använd aldrig 10.x trots teknisk kompatibilitet på grund av kända säkerhetsrisker
  • Krävs även med System.Text.Json – Du måste inkludera Newtonsoft.Json även när du använder UseSystemTextJsonSerializerWithOptions, eftersom SDK använder det internt för systemtyper
  • Fäst versionen explicit – Förlita dig inte på transitiv beroendematchning
  • Övervaka varningar – Behandla NuGet-paketnedgraderingsvarningar (NU1109) som fel i CI/CD-pipelines

Samla in diagnostik

Alla svar i SDK, inklusive CosmosException, har en Diagnostics egenskap. Den här egenskapen registrerar all information som rör den enskilda begäran, inklusive om det fanns återförsök eller tillfälliga fel.

Diagnostiken returneras som en sträng. Strängen ändras med varje version eftersom den har förbättrats för felsökning av olika scenarier. Med varje version av SDK:t kommer strängen att ha brytande ändringar i formateringen. Parsa inte strängen för att undvika brytande ändringar. Följande kodexempel visar hur du läser diagnostikloggar med hjälp av .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()
}

Metodtips för HTTP-anslutningar

.NET SDK använder HttpClient för att utföra HTTP-begäranden oavsett vilket anslutningsläge som konfigurerats.

  • I direktläge används HTTP för metadataåtgärder
  • I gatewayläge används HTTP för både dataplans- och metadataåtgärder

En av grunderna i HttpClient är att se till att HttpClient kan reagera på DNS-ändringar på ditt konto genom att anpassa livslängden för poolanslutningen. Så länge poolanslutningar hålls öppna reagerar de inte på DNS-ändringar. Den här inställningen tvingar poolade anslutningar att stängas regelbundet, vilket säkerställer att ditt program reagerar på DNS-ändringar. Vår rekommendation är att du anpassar det här värdet enligt ditt anslutningsläge och din arbetsbelastning för att balansera prestandaeffekten av att ofta skapa nya anslutningar, med behov av att reagera på DNS-ändringar (tillgänglighet). Ett 5-minutersvärde skulle vara en bra start som kan ökas om det påverkar prestanda, särskilt för Gateway-läge.

Du kan mata in din anpassade HttpClient via CosmosClientOptions.HttpClientFactory, till exempel:

// Use a Singleton instance of the SocketsHttpHandler, which you can share across any HttpClient in your application
SocketsHttpHandler socketsHttpHandler = new SocketsHttpHandler();
// Customize this value based on desired DNS refresh timer
socketsHttpHandler.PooledConnectionLifetime = TimeSpan.FromMinutes(5);

CosmosClientOptions cosmosClientOptions = new CosmosClientOptions()
{
    // Pass your customized SocketHttpHandler to be used by the CosmosClient
    // Make sure `disposeHandler` is `false`
    HttpClientFactory = () => new HttpClient(socketsHttpHandler, disposeHandler: false)
};

// Use a Singleton instance of the CosmosClient
return new CosmosClient("<connection-string>", cosmosClientOptions);

Om du använder .NET-beroendeinmatning kan du förenkla singleton-processen:

SocketsHttpHandler socketsHttpHandler = new SocketsHttpHandler();
// Customize this value based on desired DNS refresh timer
socketsHttpHandler.PooledConnectionLifetime = TimeSpan.FromMinutes(5);
// Registering the Singleton SocketsHttpHandler lets you reuse it across any HttpClient in your application
services.AddSingleton<SocketsHttpHandler>(socketsHttpHandler);

// Use a Singleton instance of the CosmosClient
services.AddSingleton<CosmosClient>(serviceProvider =>
{
    SocketsHttpHandler socketsHttpHandler = serviceProvider.GetRequiredService<SocketsHttpHandler>();
    CosmosClientOptions cosmosClientOptions = new CosmosClientOptions()
    {
        HttpClientFactory = () => new HttpClient(socketsHttpHandler, disposeHandler: false)
    };

    return new CosmosClient("<connection-string>", cosmosClientOptions);
});

Metodtips vid användning av gatewayläge

Öka System.Net MaxConnections per värd då du använder Gateway-läge. Azure Cosmos DB-begäranden görs via HTTPS/REST när du använder gatewayläge. De omfattas av standardanslutningsgränsen per värdnamn eller IP-adress. Du kan behöva ange MaxConnections ett högre värde (från 100 till 1 000) så att klientbiblioteket kan använda flera samtidiga anslutningar till Azure Cosmos DB. I .NET SDK 1.8.0 och senare är standardvärdet för ServicePointManager.DefaultConnectionLimit 50. Om du vill ändra värdet kan du ange CosmosClientOptions.GatewayModeMaxConnectionLimit ett högre värde.

Metodtips för skrivintensiva arbetsbelastningar

För arbetsuppgifter som har tunga nyttolaster, sätt begäranalternativet EnableContentResponseOnWrite till false. Tjänsten returnerar inte längre den skapade eller uppdaterade resursen till SDK:n. Eftersom programmet har objektet som skapas behöver det normalt inte tjänsten för att returnera det. Huvudvärdena är fortfarande tillgängliga, till exempel en begärandeavgift. Om du inaktiverar innehållssvaret kan du förbättra prestandan eftersom SDK:n inte längre behöver allokera minne eller serialisera svarets brödtext. Det minskar också användningen av nätverksbandbredd för att ytterligare hjälpa prestanda.

Viktigt!

Inställningen av EnableContentResponseOnWrite till false inaktiverar även svaret från en utlösaråtgärd.

Metodtips för program med flera klientorganisationer

Program som distribuerar användning mellan flera klienter där varje klientorganisation representeras av en annan databas, container eller partitionsnyckel inom samma Azure Cosmos DB-konto bör använda en enda klientinstans. En enskild klientinstans kan interagera med alla databaser, containrar och partitionsnycklar i ett konto, och det är bästa praxis att använda singleton-mönstret.

Men när varje klientorganisation representeras av ett annat Azure Cosmos DB-konto måste du skapa en separat klientinstans per konto. Singleton-mönstret gäller fortfarande för varje klient (en klient för varje konto under programmets livslängd), men om mängden klienter är hög kan antalet klienter vara svårt att hantera. Anslutningar kan öka utöver gränserna för beräkningsmiljön och orsaka anslutningsproblem.

I dessa fall rekommenderar vi att du:

  • Förstå begränsningarna i beräkningsmiljön (PROCESSOR- och anslutningsresurser). Vi rekommenderar att du använder virtuella datorer med minst 4 kärnor och 8 GB minne när det är möjligt.
  • Baserat på begränsningarna i beräkningsmiljön avgör du antalet klientinstanser (och därmed antalet klienter) som en enda beräkningsinstans kan hantera. Du kan uppskatta antalet anslutningar som öppnas per klient beroende på vilket anslutningsläge som valts.
  • Utvärdera klientdistribution mellan instanser. Om varje beräkningsinstans kan hantera en viss begränsad mängd klienter skulle belastningsutjämning och routning av klienter till olika beräkningsinstanser möjliggöra skalning när antalet klienter växer.
  • För glesa arbetsbelastningar bör du överväga att använda en minst använda cache som struktur för att hålla klientinstanserna och ta bort klienter för hyresgäster som inte nås inom en tidsperiod. Ett alternativ i .NET är MemoryCacheEntryOptions, där RegisterPostEvictionCallback kan användas för att ta bort inaktiva klienter och SetSlidingExpiration kan användas för att definiera den maximala tiden för inaktiva anslutningar.
  • Utvärdera med gatewayläge för att minska antalet nätverksanslutningar.
  • När du använder direktläge bör du överväga att justera CosmosClientOptions.IdleTcpConnectionTimeout och CosmosClientOptions.PortReuseMode i direktlägeskonfigurationen för att stänga oanvända anslutningar och hålla volymen av anslutningar under kontroll.

Nästa steg

Försöker du planera kapacitet för en migrering till Azure Cosmos DB? Du kan använda information om ditt befintliga databaskluster för kapacitetsplanering.