Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
Azure Cosmos DB è un database distribuito veloce, flessibile, facilmente scalabile e con livelli di latenza e velocità effettiva garantiti. Non è necessario apportare modifiche significative all'architettura o scrivere codice complesso per ridimensionare il database con Azure Cosmos DB. Aumentare o ridurre le prestazioni è semplice come eseguire una singola chiamata API. Per altre informazioni, vedere Effettuare il provisioning della velocità effettiva per un contenitore oppure Effettuare il provisioning della velocità effettiva per un database.
Poiché si accede ad Azure Cosmos DB tramite chiamate di rete, è possibile apportare ottimizzazioni lato client per ottenere prestazioni ottimali quando si usa SQL .NET SDK.
Se si sta cercando di migliorare le prestazioni del database, si prendano in considerazione le opzioni presentate nelle sezioni seguenti.
Raccomandazioni relative all'hosting
Attivare Garbage Collection lato server
In alcuni casi, può essere utile ridurre la frequenza di Garbage Collection. In .NET impostare gcServer su true.
Aumentare il carico di lavoro client
Se si esegue il test a throughput elevato o a velocità superiori a 50.000 Request Units per secondo (RU/s), l'applicazione client potrebbe diventare un collo di bottiglia del carico di lavoro perché il computer potrebbe saturare la CPU o la rete. Se si arriva a questo punto, è possibile continuare a spingere l'account Azure Cosmos DB espandendo le applicazioni client su più server.
Annotazioni
Un utilizzo elevato della CPU può causare un aumento della latenza e le eccezioni di timeout delle richieste.
Operazioni sui metadati
Non verificare la presenza di un database o di un contenitore chiamando Create...IfNotExistsAsync o Read...Async nel percorso critico prima di eseguire un'operazione sugli elementi. La convalida deve essere eseguita solo all'avvio dell'applicazione quando è necessario, se si prevede che vengano eliminate (in caso contrario non è necessario). Queste operazioni sui metadati generano un'ulteriore latenza end-to-end aggiuntiva, non hanno un contratto di servizio e prevedono limitazioni separate che non vengono dimensionate in modo diverso dalle operazioni sui dati.
Registrazione e traccia
Per alcuni ambienti è abilitato .NET DefaultTraceListener. DefaultTraceListener pone problemi di prestazioni negli ambienti di produzione causando colli di bottiglia elevati di CPU e I/O. Controllare e assicurarsi che DefaultTraceListener sia disabilitato per l'applicazione rimuovendolo da TraceListeners negli ambienti di produzione.
Le versioni dell'SDK successive alla 3.23.0 la rimuovono automaticamente quando vengono rilevate. Con le versioni precedenti, è possibile rimuoverlo usando i comandi seguenti:
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
}
Disponibilità elevata
Per indicazioni generali sulla configurazione della disponibilità elevata in Azure Cosmos DB, vedere Disponibilità elevata in Azure Cosmos DB.
Oltre a una buona configurazione di base nella piattaforma di database, esistono tecniche specifiche che possono essere implementate in .NET SDK stesso, che possono essere utili per scenari di interruzione. Due strategie rilevanti sono la strategia di disponibilità basata su soglia e l'interruttore a livello di partizione.
Strategia di disponibilità basata su soglia
La strategia di disponibilità basata su soglia può migliorare la latenza di coda e la disponibilità inviando richieste di lettura parallele alle regioni secondarie (come definito in ApplicationPreferredRegions) e accettando la risposta più rapida. Questo approccio può ridurre drasticamente l'effetto di interruzioni a livello di area o condizioni di latenza elevata sulle prestazioni dell'applicazione.
Configurazione di esempio:
La configurazione di questa operazione può essere eseguita usando CosmosClientBuilder:
CosmosClient client = new CosmosClientBuilder("connection string")
.WithApplicationPreferredRegions(
new List<string> { "East US", "East US 2", "West US" } )
.WithAvailabilityStrategy(
AvailabilityStrategy.CrossRegionHedgingStrategy(
threshold: TimeSpan.FromMilliseconds(500),
thresholdStep: TimeSpan.FromMilliseconds(100)
))
.Build();
In alternativa, configurando le opzioni e aggiungendole a CosmosClient:
CosmosClientOptions options = new CosmosClientOptions()
{
AvailabilityStrategy
= AvailabilityStrategy.CrossRegionHedgingStrategy(
threshold: TimeSpan.FromMilliseconds(500),
thresholdStep: TimeSpan.FromMilliseconds(100)
)
ApplicationPreferredRegions = new List<string>() { "East US", "East US 2", "West US"},
};
CosmosClient client = new CosmosClient(
accountEndpoint: "account endpoint",
authKeyOrResourceToken: "auth key or resource token",
clientOptions: options);
Funzionamento:
Richiesta iniziale: Al momento T1, viene effettuata una richiesta di lettura all'area primaria, ad esempio Stati Uniti orientali. L'SDK attende una risposta fino a 500 millisecondi (valore
threshold).Seconda richiesta: Se non è presente alcuna risposta dall'area primaria entro 500 millisecondi, viene inviata una richiesta parallela all'area preferita successiva, ad esempio Stati Uniti orientali 2.
Terza richiesta: Se né l'area primaria né quella secondaria rispondono entro 600 millisecondi (500 ms + 100 ms, il
thresholdStepvalore), l'SDK invia un'altra richiesta parallela alla terza area preferita ,ad esempio Stati Uniti occidentali.La risposta più veloce vince: Qualsiasi area risponda per prima, la risposta viene accettata e le altre richieste parallele vengono ignorate.
Annotazioni
Se la prima area preferita restituisce un codice di stato di errore non transiente (ad esempio, documento non trovato, errore di autorizzazione o conflitto), l'operazione non riesce rapidamente, perché la strategia di disponibilità non offre alcun vantaggio in questo scenario.
Interruttore a livello di partizione
L'interruttore a livello di partizione (PPCB) è una funzionalità di .NET SDK che migliora la disponibilità e la latenza monitorando le partizioni fisiche non integre. Se abilitata, consente di instradare le richieste alle aree più integre, impedendo errori a catena a causa di problemi specifici dell'area o della partizione. La funzionalità è indipendente dal failover attivato dal back-end ed è controllata tramite variabili di ambiente.
Questa funzionalità è disabilitata per impostazione predefinita, ma viene abilitata automaticamente quando è abilitato il failover a livello di partizione.
Come funziona
-
Rilevamento degli errori: Quando vengono osservati errori specifici, ad
503 Service Unavailableesempio ,408 Request Timeouto token di annullamento, l'SDK conta errori consecutivi per una partizione. -
Attivazione del failover: Una volta raggiunta una soglia configurata di errori consecutivi, l'SDK reindirizza le richieste per tale intervallo di chiavi di partizione all'area preferita successiva usando
GlobalPartitionEndpointManagerCore.TryMarkEndpointUnavailableForPartitionKeyRange. - Ripristino in background: durante il failover viene avviata un'attività in background per rivalutare periodicamente l'integrità della partizione in errore tentando di connettersi a tutte e quattro le repliche. Una volta integro, l'SDK rimuove l'override e torna all'area primaria.
Comportamento per tipo di account
- Scrittura a singola area (master singolo): Solo le richieste di lettura partecipano alla logica di failover PPCB.
- Scrittura in più aree (multimaster): Le richieste di lettura e scrittura usano la logica di failover PPCB.
Opzioni di configurazione
Usare le variabili di ambiente seguenti per configurare PPCB:
| Variabile di ambiente | Description | Predefinito |
|---|---|---|
AZURE_COSMOS_CIRCUIT_BREAKER_ENABLED |
Abilita o disabilita la funzionalità PPCB. | false |
AZURE_COSMOS_PPCB_CONSECUTIVE_FAILURE_COUNT_FOR_READS |
Errori di lettura consecutivi che attivano il failover. | 10 |
AZURE_COSMOS_PPCB_CONSECUTIVE_FAILURE_COUNT_FOR_WRITES |
Errori di scrittura consecutivi per attivare il failover. | 5 |
AZURE_COSMOS_PPCB_ALLOWED_PARTITION_UNAVAILABILITY_DURATION_IN_SECONDS |
Tempo prima di rivalutare l'integrità della partizione. |
5 Secondi |
AZURE_COSMOS_PPCB_STALE_PARTITION_UNAVAILABILITY_REFRESH_INTERVAL_IN_SECONDS |
Intervallo per l'aggiornamento in background dell'integrità della partizione. |
60 Secondi |
Annotazioni
L'SDK attualmente non dispone di un trigger di failback affidabile per le letture. Un controllo integrità in background tenta invece gradualmente di riabilitare l'area originale quando tutte e quattro le repliche sono reattive.
Confronto delle ottimizzazioni della disponibilità
Strategia di disponibilità basata su soglia:
- Vantaggio: riduce la latenza della coda inviando richieste di lettura parallele alle aree secondarie e migliora la disponibilità annullando le richieste che comportano timeout di rete.
- Trade-off: comporta costi aggiuntivi di RUs rispetto al circuit breaker, a causa di richieste parallele aggiuntive tra regioni (anche se solo durante i periodi in cui le soglie vengono superate).
- Caso d'uso: ottimale per i carichi di lavoro con un numero elevato di operazioni di lettura in cui la riduzione della latenza è critica e un costo aggiuntivo (sia in termini di carico di UR che di utilizzo della CPU client) è accettabile. Le operazioni di scrittura possono anche trarre vantaggio, se si è scelto di usare il criterio di ripetizione dei tentativi di scrittura non idempotente e l'account dispone di scritture multiregione.
Interruttore a livello di partizione:
- Vantaggi: migliora la disponibilità e la latenza evitando partizioni non integre, assicurando che le richieste vengano instradate alle aree più integre.
- Compromesso: non comporta costi di ur maggiori, ma può comunque consentire una perdita di disponibilità iniziale per le richieste che comportano timeout di rete.
- Caso d'uso: Ideale per carichi di lavoro pesanti in scrittura o misti in cui le prestazioni costanti sono essenziali, soprattutto quando si gestiscono partizioni che potrebbero diventare non funzionanti correttamente a intermittenza.
Entrambe le strategie possono essere usate insieme per migliorare la disponibilità di lettura e scrittura e ridurre la latenza della coda. L'interruttore a livello di partizione può gestire vari scenari di errore temporanei, inclusi quelli che potrebbero causare repliche con prestazioni lente, senza la necessità di eseguire richieste parallele. Inoltre, l'aggiunta di una strategia di disponibilità basata su soglia riduce ulteriormente al minimo la latenza della coda ed elimina la perdita di disponibilità, se il costo aggiuntivo delle UR è accettabile.
Implementando queste strategie, gli sviluppatori possono garantire che le applicazioni rimangano resilienti, mantengano prestazioni elevate e forniscano un'esperienza utente migliore anche durante interruzioni a livello di area o condizioni di latenza elevata.
Aree geografiche escluse
La funzionalità delle aree escluse consente un controllo granulare sul routing delle richieste consentendo di escludere aree specifiche dalle località preferite in base alle richieste. Questa funzionalità è disponibile in Azure Cosmos DB .NET SDK versione 3.37.0 e successive.
Vantaggi principali:
- Gestire la limitazione della frequenza: quando si riscontrano risposte 429 (troppe richieste), instradare automaticamente le richieste alle aree alternative con la velocità effettiva disponibile
- Routing di destinazione: assicurarsi che le richieste vengano gestite da aree specifiche escludendo tutte le altre
- Ignorare l'ordine preferito: eseguire l'override dell'elenco delle aree preferite predefinite per le singole richieste senza creare client separati
Configurazione:
Le aree escluse possono essere configurate a livello di richiesta usando la ExcludeRegions proprietà :
CosmosClientOptions clientOptions = new CosmosClientOptions()
{
ApplicationPreferredRegions = new List<string> {"West US", "Central US", "East US"}
};
CosmosClient client = new CosmosClient(connectionString, clientOptions);
Database db = client.GetDatabase("myDb");
Container container = db.GetContainer("myContainer");
//Request will be served out of the West US region
await container.ReadItemAsync<dynamic>("item", new PartitionKey("pk"));
//By using ExcludeRegions, we are able to bypass the ApplicationPreferredRegions list
// and route a request directly to the East US region
await container.ReadItemAsync<dynamic>(
"item",
new PartitionKey("pk"),
new ItemRequestOptions()
{
ExcludeRegions = new List<string>() { "West US", "Central US" }
});
Esempio di caso d'uso : gestione della limitazione della frequenza:
ItemResponse<CosmosItem> item;
item = await container.ReadItemAsync<CosmosItem>("id", partitionKey);
if (item.StatusCode == HttpStatusCode.TooManyRequests)
{
ItemRequestOptions requestOptions = new ItemRequestOptions()
{
ExcludeRegions = new List<string>() { "East US" }
};
item = await container.ReadItemAsync<CosmosItem>("id", partitionKey, requestOptions);
}
La funzionalità funziona anche con query e altre operazioni:
QueryRequestOptions queryRequestOptions = new QueryRequestOptions()
{
ExcludeRegions = new List<string>() { "East US" }
};
using (FeedIterator<CosmosItem> queryFeedIterator = container.GetItemQueryIterator<CosmosItem>(
queryDefinition,
requestOptions: queryRequestOptions))
{
while(queryFeedIterator.HasMoreResults)
{
var item = await queryFeedIterator.ReadNextAsync();
}
}
Ottimizzazione della coerenza e della disponibilità
La funzionalità delle aree escluse offre un meccanismo aggiuntivo per bilanciare i compromessi tra coerenza e disponibilità nell'applicazione. Questa funzionalità è particolarmente utile negli scenari dinamici in cui i requisiti possono cambiare in base alle condizioni operative:
Gestione dinamica dell'interruzione: quando si verifica un'interruzione di un'area primaria e le soglie di interruzione del circuito a livello di partizione non sono sufficienti, le aree escluse abilitano il failover immediato senza modifiche al codice o riavvii dell'applicazione. In questo modo si ottiene una risposta più rapida ai problemi a livello di area rispetto all'attesa dell'attivazione automatica dell'interruttore.
Preferenze di coerenza condizionale: le applicazioni possono implementare strategie di coerenza diverse in base allo stato operativo:
- Stato stabile: classificare in ordine di priorità le letture coerenti escludendo tutte le aree ad eccezione del database primario, garantendo la coerenza dei dati al costo potenziale della disponibilità
- Scenari di interruzione: favorire la disponibilità rispetto alla coerenza rigorosa consentendo il routing tra aree, accettando potenziale ritardo dei dati in cambio della disponibilità continua del servizio
Questo approccio consente a meccanismi esterni, ad esempio gestori di traffico o servizi di bilanciamento del carico, di orchestrare le decisioni di failover mentre l'applicazione mantiene il controllo sui requisiti di coerenza tramite i modelli di esclusione dell'area.
Quando vengono escluse tutte le aree, le richieste verranno instradate all'area primaria/hub. Questa funzionalità funziona con tutti i tipi di richiesta, incluse le query ed è particolarmente utile per gestire le istanze client singleton, ottenendo al tempo stesso un comportamento di routing flessibile.
Rete
Criteri di connessione: usare la modalità di connessione diretta
La modalità di connessione predefinita di .NET V3 SDK è diretta con il protocollo TCP. Quando si crea l'istanza CosmosClient in CosmosClientOptions, viene configurata la modalità di connessione. Per altre informazioni sulle diverse opzioni di connettività, consultare l'articolo modalità di connettività.
CosmosClient client = new CosmosClient(
"<nosql-account-endpoint>",
tokenCredential
new CosmosClientOptions
{
ConnectionMode = ConnectionMode.Gateway // ConnectionMode.Direct is the default
}
);
Esaurimento della porta temporanea
Se si rileva un volume di connessione elevato o un uso elevato delle porte nelle istanze, verificare prima di tutto che le istanze client siano singleton. In altre parole, le istanze client devono essere univoche per la durata dell'applicazione.
Quando è in esecuzione sul protocollo TCP, il client ottimizza la latenza usando le connessioni di lunga durata. Ciò è in contrasto con il protocollo HTTPS, che termina le connessioni dopo due minuti di inattività.
Negli scenari con accesso sporadico, se si nota un numero di connessioni superiore rispetto alla modalità di accesso Gateway, è possibile:
- Configurare la proprietà CosmosClientOptions.PortReuseMode su
PrivatePortPool(efficace con le versioni del framework 4.6.1 e successive e .NET Core 2.0 e successive). Questa proprietà consente all'SDK di usare un piccolo pool di porte temporanee per vari endpoint di destinazione Azure Cosmos DB. - Configurare la proprietà CosmosClientOptions.IdleTcpConnectionTimeout maggiore o uguale a 10 minuti. I valori consigliati sono compresi tra 20 minuti e 24 ore.
Ai fini delle prestazioni, collocare i client nella stessa area di Azure
Quando possibile, posizionare eventuali applicazioni che chiamano Azure Cosmos DB nella stessa area del database Azure Cosmos DB. Ecco un confronto approssimativo: le chiamate ad Azure Cosmos DB eseguite nella stessa area vengono completate da 1 millisecondo (ms) a 2 ms, ma la latenza tra la costa occidentale e quella orientale degli Stati Uniti è superiore a 50 ms. Questa latenza può variare da richiesta a richiesta, in base alla route seguita dalla richiesta durante il passaggio dal client al limite del data center di Azure.
È possibile ottenere la latenza più bassa possibile assicurandosi che l'applicazione chiamante sia situata nella stessa area di Azure dell'endpoint Azure Cosmos DB configurato. Per un elenco delle aree disponibili, vedere Aree di Azure.
Aumentare il numero di thread/attività
Poiché le chiamate ad Azure Cosmos DB vengono eseguite sulla rete, può essere necessario modificare il grado di concorrenza delle richieste in modo che i tempi di attesa dell'applicazione client tra le richieste siano minimi. Ad esempio, se usi la Task Parallel Library di .NET, crea dell'ordine di centinaia di attività che leggono o scrivono su Azure Cosmos DB.
Abilitare la rete accelerata per ridurre la latenza e l'instabilità della CPU
È consigliabile seguire le istruzioni per abilitare la rete accelerata nella macchina virtuale Windows o Linux di Azure per ottimizzare le prestazioni.
Senza rete accelerata, l'I/O che transita tra la macchina virtuale di Azure e altre risorse di Azure potrebbe essere instradato inutilmente attraverso un host e un commutatore virtuale situati tra la macchina virtuale e la sua scheda di rete. La presenza dell'host e del commutatore virtuale inline nel percorso dei dati non solo aumenta la latenza e l'instabilità nel canale di comunicazione, ma sottrae anche cicli della CPU alla macchina virtuale. Con la rete accelerata, le interfacce VM comunicano direttamente con la NIC senza intermediari; i dettagli dei criteri di rete che erano gestiti dall'host e dal commutatore virtuale sono ora gestiti a livello hardware dalla NIC; l'host e il commutatore virtuale vengono bypassati. Quando si abilita la rete accelerata, è in genere possibile prevedere una latenza più bassa e una velocità effettiva più elevata, oltre a una maggiore latenza coerente e a un minore utilizzo della CPU.
Limitazioni: la rete accelerata deve essere supportata nel sistema operativo della macchina virtuale e può essere abilitata solo quando la macchina virtuale viene arrestata e deallocata. La macchina virtuale non può essere distribuita con Azure Resource Manager. App Service non ha rete accelerata abilitata.
Per altri dettagli, vedere le istruzioni di Windows e Linux .
Uso dell'SDK
Installare l'SDK più recente
Agli SDK di Azure Cosmos DB vengono apportati continui miglioramenti per offrire prestazioni ottimali. Per determinare la versione di SDK più recente e verificare i miglioramenti, vedere le pagine relative agli SDK di Azure Cosmos DB.
Usare le API di streaming
.NET SDK V3 contiene API di flusso che possono ricevere e restituire dati senza serializzazione.
Le applicazioni di livello intermedio che non usano le risposte direttamente dall'SDK, ma le inoltrano ad altri livelli di applicazione possono trarre vantaggio dalle API di flusso. Per esempi di gestione dei flussi, vedere gli esempi di gestione degli elementi.
Utilizzare un client Azure Cosmos DB singleton per l'intero ciclo di vita dell'applicazione
Ogni CosmosClient istanza è thread-safe ed esegue una gestione efficiente della connessione e la memorizzazione nella cache degli indirizzi quando opera in modalità diretta. Per consentire una gestione efficiente delle connessioni e prestazioni migliori del client SDK, è consigliabile usare una singola istanza per ogni AppDomain per la durata dell'applicazione per ogni account con cui questa interagisce.
Per le applicazioni multi-tenant che gestiscono più account, vedere le procedure consigliate correlate.
Quando si lavora su Funzioni di Azure, le istanze devono seguire le linee guida esistenti e mantenere una singola istanza.
Evitare le chiamate di blocco
L'SDK di Azure Cosmos DB deve essere progettato per elaborare più richieste contemporaneamente. Le API asincrone consentono a un piccolo pool di thread di gestire migliaia di richieste simultanee senza attendere chiamate di blocco. Anziché attendere il completamento di un'attività sincrona a esecuzione prolungata, il thread può lavorare su un'altra richiesta.
Un problema di prestazioni comune nelle app che usano l'SDK di Azure Cosmos DB sono le chiamate di blocco che potrebbero essere asincrone. Molte chiamate di blocco sincrono portano all'esaurimento del pool di thread e a tempi di risposta degradati.
Non:
- Bloccare l'esecuzione asincrona chiamando Task.Wait o Task.Result.
- Usare Task.Run per rendere asincrona un'API sincrona.
- Acquisire blocchi in percorsi di codice comuni. .NET SDK di Azure Cosmos DB è più efficiente quando progettato per eseguire codici in parallelo.
- Chiamare Task.Run e attendere immediatamente. ASP.NET Core esegue già il codice dell'app nei normali thread del Thread Pool, quindi la chiamata a Task.Run comporta solo una non necessaria pianificazione del Thread Pool. Anche se il codice pianificato bloccherebbe un thread, Task.Run non impedisce che ciò accada.
- Non usare ToList() in
Container.GetItemLinqQueryable<T>(), che usa chiamate di blocco per svuotare in modo sincrono la query. Usare ToFeedIterator() per svuotare la query in modo asincrono.
Cosa fare:
- Chiamare le API .NET di Azure Cosmos DB in modo asincrono.
- L'intero stack di chiamate è asincrono per trarre vantaggio dai criteri async/await.
Un profiler, ad esempio PerfView, può essere usato per trovare i thread aggiunti di frequente al pool di thread. L'evento Microsoft-Windows-DotNETRuntime/ThreadPoolWorkerThread/Start indica un thread aggiunto al pool di thread.
Disabilitare la risposta al contenuto nelle operazioni di scrittura
Per i carichi di lavoro con payload di creazione massicci, impostare l'opzione di richiesta EnableContentResponseOnWrite su false. Il servizio non restituisce più la risorsa creata o aggiornata all'SDK. In genere, poiché l'applicazione ha l'oggetto che viene creato, non è necessario che il servizio lo restituisca. I valori dell'intestazione sono ancora accessibili, come un addebito della richiesta. La disabilitazione della risposta al contenuto può contribuire a migliorare le prestazioni, perché l'SDK non deve più allocare memoria o serializzare il corpo della risposta. Riduce inoltre l'uso della larghezza di banda di rete per migliorare le prestazioni.
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
Abilitare la funzionalità Bulk per ottimizzare la velocità effettiva anziché la latenza
Abilitare la funzionalità bulk per gli scenari in cui il carico di lavoro richiede una grande quantità di velocità effettiva e la latenza non è importante. Per ulteriori informazioni su come abilitare la funzionalità Bulk e sugli scenari da usare, consultare Introduzione al supporto Bulk.
Aumentare il valore di System.Net MaxConnections per host se si usa la modalità Gateway
Le richieste di Azure Cosmos DB vengono effettuate tramite HTTPS/REST quando si usa la modalità Gateway. Sono soggette al limite di connessione predefinito per nome host o indirizzo IP. Può essere necessario impostare MaxConnections su un valore più alto (da 100 1.000) in modo che la libreria client possa usare più connessioni simultanee ad Azure Cosmos DB. In .NET SDK 1.8.0 e versioni successive il valore predefinito per ServicePointManager.DefaultConnectionLimit è 50. Per modificare il valore, è possibile impostare Documents.Client.ConnectionPolicy.MaxConnectionLimit su un valore più alto.
Aumentare il numero di thread/attività
Vedere Aumentare il numero di thread/attività nella sezione Rete di questo articolo.
Gestione delle dipendenze di Newtonsoft.Json
Informazioni generali
Azure Cosmos DB .NET SDK ha una dipendenza da Newtonsoft.Json per le operazioni di serializzazione JSON.
Questa dipendenza non viene gestita automaticamente . È necessario aggiungere Newtonsoft.Json in modo esplicito come dipendenza diretta nel progetto.
L'SDK viene compilato internamente in Newtonsoft.Json 10.x, che presenta una vulnerabilità di sicurezza nota. Anche se l'SDK è tecnicamente compatibile con la versione 10.x e l'uso dell'SDK di Newtonsoft.Json non è soggetto al problema di sicurezza segnalato, è comunque consigliabile usare la versione 13.0.3 o successiva per evitare potenziali problemi di sicurezza o conflitti. Le versioni 13.x includono modifiche di rilievo, ma i modelli di utilizzo dell'SDK sono compatibili con queste modifiche.
Importante
Questa dipendenza è necessaria anche quando si usa System.Text.Json per i tipi definiti dall'utente tramite CosmosClientOptions.UseSystemTextJsonSerializerWithOptions, perché le operazioni interne dell'SDK usano ancora Newtonsoft.Json per i tipi di sistema.
Configurazione consigliata
Aggiungere Newtonsoft.Json sempre in modo esplicito la versione 13.0.3 o successiva come dipendenza diretta quando si usa Azure Cosmos DB .NET SDK v3. Non usare la versione 10.x a causa di vulnerabilità di sicurezza note.
Per progetti Standard .csproj
<ItemGroup>
<PackageReference Include="Microsoft.Azure.Cosmos" Version="3.47.0" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.4" />
</ItemGroup>
Per i progetti che usano la gestione pacchetti centrale
Se il progetto usa Directory.Packages.props:
<Project>
<ItemGroup>
<PackageVersion Include="Microsoft.Azure.Cosmos" Version="3.47.0" />
<PackageVersion Include="Newtonsoft.Json" Version="13.0.4" />
</ItemGroup>
</Project>
Risoluzione dei conflitti di versione
Informazioni di riferimento su Newtonsoft.Json mancanti
Se si verifica un errore di compilazione simile al seguente:
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.
Questo errore viene generato intenzionalmente dalle destinazioni di compilazione di Cosmos DB SDK per assicurarsi che la dipendenza sia configurata correttamente.
Soluzione per le applicazioni:
Aggiungere un riferimento esplicito a Newtonsoft.Json, come illustrato nella sezione Configurazione consigliata precedente.
Soluzione per le librerie:
Se si sta creando una libreria (non un'applicazione) e si intende rinviare la dipendenza Newtonsoft.Json ai consumatori della libreria, è possibile ignorare questa verifica impostando la proprietà MSBuild in .csproj:
<PropertyGroup>
<AzureCosmosDisableNewtonsoftJsonCheck>true</AzureCosmosDisableNewtonsoftJsonCheck>
</PropertyGroup>
Avvertimento
Usare questo bypass solo quando si compilano librerie in cui gli utenti finali forniranno la dipendenza Newtonsoft.Json. Per le applicazioni, aggiungere sempre il riferimento esplicito.
Conflitti di versione del pacchetto
Se si verificano errori di compilazione come:
error NU1109: Detected package downgrade: Newtonsoft.Json from 13.0.4 to centrally defined 13.0.3
Soluzione:
Identificare la versione richiesta controllando quali pacchetti necessitano di versioni più recenti:
dotnet list package --include-transitive | Select-String "Newtonsoft.Json"Aggiornare la versione centralizzata del pacchetto in modo che corrisponda o superi la versione più recente richiesta:
<PackageVersion Include="Newtonsoft.Json" Version="13.0.4" />Pulizia e ricompilazione:
dotnet clean dotnet restore dotnet build
Compatibilità delle versioni
La tabella seguente illustra le versioni sicure minime consigliate di Newtonsoft.Json per ogni versione di Cosmos DB SDK. Anche se l'SDK può funzionare tecnicamente con 10.x, queste versioni non devono mai essere usate a causa di vulnerabilità di sicurezza.
| Versione di Cosmos DB SDK | Versione minima sicura | Recommended |
|---|---|---|
| 3.47.0+ | 13.0.3 | 13.0.4 |
| 3.54.0+ | 13.0.4 | 13.0.4 |
Suggerimento
Quando si usa .NET Aspire 13.0.0 o versione successiva, assicurarsi che Newtonsoft.Json sia alla versione 13.0.4 per evitare conflitti con i componenti di Azure di Aspire.
Migliori pratiche
- Aggiungere sempre come dipendenza diretta : l'SDK non gestisce automaticamente questa dipendenza
- Usare la versione 13.0.3 o successiva : non usare mai la versione 10.x nonostante la compatibilità tecnica, a causa di vulnerabilità di sicurezza note
-
Obbligatorio anche con System.Text.Json : è necessario includere Newtonsoft.Json anche quando si usa
UseSystemTextJsonSerializerWithOptions, perché l'SDK lo usa internamente per i tipi di sistema - Aggiungere la versione in modo esplicito : non fare affidamento sulla risoluzione delle dipendenze transitive
- Avvisi di monitoraggio - Trattare gli avvisi di downgrade del pacchetto NuGet (NU1109) come errori nelle pipeline CI/CD
Operazioni di query
Per le operazioni di query, vedere i suggerimenti sulle prestazioni per le query.
Politica di indicizzazione
Escludere i percorsi non usati dall'indicizzazione per scritture più veloci
I criteri di indicizzazione di Azure Cosmos DB consentono anche di specificare i percorsi dei documenti da includere o escludere dall'indicizzazione usando i percorsi di indicizzazione (IndexingPolicy.IncludedPaths e IndexingPolicy.ExcludedPaths).
L'indicizzazione solo dei percorsi necessari può migliorare le prestazioni di scrittura, ridurre gli addebiti delle UR per le operazioni di scrittura e ridurre l'archiviazione degli indici per gli scenari in cui i modelli di query sono noti in anticipo. Ciò è dovuto al fatto che i costi di indicizzazione sono correlati direttamente al numero di percorsi univoci indicizzati. Ad esempio, il codice seguente illustra come escludere un'intera sezione dei documenti (un sottoalbero) dall'indicizzazione usando il * carattere jolly:
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);
Per altre informazioni, vedere l'articolo relativo ai criteri di indicizzazione di Azure Cosmos DB.
Capacità di produzione
Misurare e ottimizzare per ridurre l'uso di UR/s
Azure Cosmos DB offre un set completo di operazioni di database. Queste operazioni includono query relazionali e gerarchiche con funzioni definite dall'utente (UDF), stored procedure e trigger, operative nei documenti in una raccolta di database.
I costi associati a ognuna di queste operazioni varia in base a CPU, I/O e memoria che sono necessari per il completamento dell'operazione. Invece di occuparsi della pianificazione e della gestione delle risorse hardware, sarà possibile usare un' unità richiesta come misura singola per le risorse che sono necessarie per eseguire diverse operazioni di database e rispondere a una richiesta dell'applicazione.
Viene eseguito il provisioning della velocità effettiva in base al numero di unità richiesta impostato per ogni contenitore. Il consumo di UR viene valutato in termini di unità al secondo. Le applicazioni che superano la frequenza di RU di cui è stato effettuato il provisioning per il contenitore sono limitate fino a quando la frequenza scende al di sotto del livello fornito per il contenitore. Se l'applicazione richiede un livello di velocità effettiva superiore, è possibile aumentare la velocità effettiva effettuando il provisioning di più UR.
La complessità di una query influisce sul numero di UR utilizzate per un'operazione. Il numero di predicati, la natura dei predicati, il numero di file UDF e le dimensioni del set di dati di origine sono tutti fattori che incidono sul costo delle operazioni di query.
Per misurare il sovraccarico di qualsiasi operazione (creazione, aggiornamento o eliminazione), esaminare l'intestazione x-ms-request-charge (o la proprietà equivalente RequestCharge in ResourceResponse<T> o FeedResponse<T> in .NET SDK) per misurare il numero di UR utilizzate dalle operazioni:
// 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);
}
L'addebito richiesta restituito in questa intestazione è una frazione della velocità effettiva con provisioning (ovvero 2.000 UR/s). Se, ad esempio, la query precedente restituisce 1.000 documenti da 1 KB, il costo dell'operazione è 1.000. Entro un secondo, il server rispetterà quindi solo due richieste di questo tipo prima di limitare la velocità delle richieste successive. Per altre informazioni, vedere Unità richiesta e il Calcolatore di unità richiesta.
Gestire la limitazione della frequenza o una frequenza di richieste troppo elevata
Quando un client prova a superare la velocità effettiva riservata per un account, non si verifica alcun calo delle prestazioni del server e l'uso della capacità della velocità effettiva non supera il livello riservato. Il server termina preventivamente la richiesta con RequestRateTooLarge (codice di stato HTTP 429). Restituisce un'intestazione x-ms-retry-after-ms che indica la quantità di tempo, espressa in millisecondi, che l'utente deve attendere prima di ripetere la richiesta.
HTTP Status 429,
Status Line: RequestRateTooLarge
x-ms-retry-after-ms :100
Tutti gli SDK intercettano implicitamente questa risposta, rispettano l'intestazione retry-after specificata dal server e ripetono la richiesta. A meno che all'account non accedano contemporaneamente più client, il tentativo successivo riuscirà.
Se si dispone di più client che operano complessivamente a una velocità costantemente superiore a quella della richiesta, il numero di tentativi predefinito attualmente impostato internamente dal client su 9 potrebbe non essere sufficiente. In tal caso, il client genera un'eccezione CosmosException con codice di stato 429 per l'applicazione.
È possibile modificare il numero di tentativi predefinito impostando RetryOptions nell'istanza CosmosClientOptions. Per impostazione predefinita, l'eccezione CosmosException con codice di stato 429 viene restituita dopo un tempo di attesa cumulativo di 30 secondi, se la richiesta continua a funzionare al di sopra della frequenza delle richieste. Questo errore si verifica anche quando il numero di ripetizioni dei tentativi corrente è inferiore al numero massimo di tentativi, indipendentemente dal fatto che si tratti del valore predefinito 9 o di un valore definito dall'utente.
Il comportamento automatizzato per la ripetizione dei tentativi consente di migliorare la resilienza e l'usabilità per la maggior parte delle applicazioni. Ma potrebbe non essere il comportamento migliore quando si eseguono benchmark delle prestazioni, soprattutto quando si misura la latenza. La latenza osservata dal client presenterà dei picchi se l'esperimento raggiunge il limite del server e fa in modo che l'SDK client ripeta automaticamente i tentativi. Per evitare i picchi di latenza durante gli esperimenti relativi alle prestazioni, misurare l'addebito che viene restituito da ogni operazione e assicurarsi che le richieste operino al di sotto della frequenza delle richieste riservata.
Per altre informazioni, vedere Unità richiesta.
Per ottenere una velocità effettiva maggiore, progettare documenti di dimensioni minori
L'addebito per le richieste (ovvero il costo di elaborazione delle richieste) per un'operazione specifica è correlato direttamente alle dimensioni del documento. Le operazioni sui documenti di grandi dimensioni sono più costose rispetto alle operazioni sui documenti di piccole dimensioni.