Quando lavoriamo con un database, l’ottimizzazione è cruciale e fondamentale in termini di prestazioni ed efficienza dell’applicazione. Allo stesso modo, in Azure Cosmos DB, l’ottimizzazione è fondamentale per massimizzare l’efficienza, ridurre i costi e garantire che la tua applicazione si scaldi in modo efficace. Di seguito sono riportate alcune delle migliori pratiche con esempi di codice per ottimizzare le prestazioni in Azure Cosmos DB.
1. Selezione della chiave di partizione corretta
Scegliere una chiave di partizione appropriata è vitale per i database distribuiti come Cosmos DB. Una buona chiave di partizione garantisce che i dati siano distribuiti uniformemente tra le partizioni, riducendo i punti caldi e migliorando le prestazioni.
La selezione di una chiave di partizione è semplice ma molto importante in fase di progettazione in Azure Cosmos DB. Una volta che abbiamo selezionato la chiave di partizione, non è possibile cambiarla in loco.
Migliore Pratica
- Seleziona una chiave di partizione con alta cardinalità (molti valori unici).
- Assicurati che distribuisca letture e scritture in modo uniforme.
- Tieni insieme i dati correlati per ridurre al minimo le query tra partizioni.
Esempio: Creare un contenitore con una chiave di partizione ottimale
var database = await cosmosClient.CreateDatabaseIfNotExistsAsync("YourDatabase");
var containerProperties = new ContainerProperties
{
Id = "myContainer",
PartitionKeyPath = "/customerId" // Partition key selected to ensure balanced distribution
};
// Crea il contenitore con una capacità di 400 RU/s provisionata
var container = await database.CreateContainerIfNotExistsAsync(containerProperties, throughput: 400);
2. Corretta Uso dell’indicizzazione
In Azure Cosmos DB, gli indici vengono applicati a tutte le proprietà per impostazione predefinita, il che può essere vantaggioso ma potrebbe comportare un aumento dei costi di archiviazione e RU/s. Per migliorare le prestazioni delle query e ridurre le spese, considera la personalizzazione della policy di indicizzazione. Cosmos DB supporta tre tipi di indici: Indici di intervallo, Indici spaziali e Indici compositi. Usa il tipo giusto saggiamente.
Prassi consigliata
- Ecludere i campi non necessari dall’indicizzazione.
- Usa indici compositi per le query multi-campo.
Esempio: Policy di indicizzazione personalizzata
{
"indexingPolicy": {
"automatic": true,
"indexingMode": "consistent", // Can use 'none' or 'lazy' to reduce write costs
"includedPaths": [
{
"path": "/orderDate/?", // Only index specific fields like orderDate
"indexes": [
{
"kind": "Range",
"dataType": "Number"
}
]
}
],
"excludedPaths": [
{
"path": "/largeDataField/*" // Exclude large fields not used in queries
}
]
}
}
Esempio: Aggiunta di un indice composito per interrogazioni ottimizzate
{
"indexingPolicy": {
"compositeIndexes": [
[
{ "path": "/lastName", "order": "ascending" },
{ "path": "/firstName", "order": "ascending" }
]
]
}
}
Puoi leggere di più sui tipi di indicizzazione qui.
3. Ottimizza le query
Interrogare in modo efficiente è cruciale per ridurre le unità di richiesta (RU/s) e migliorare le prestazioni in Azure Cosmos DB. Il costo RU/s dipende dalla complessità e dimensione della query.
Utilizzare esecutori bulk può ridurre ulteriormente i costi diminuendo le RU consumate per operazione. Questa ottimizzazione aiuta a gestire efficacemente l’uso di RU e a ridurre le spese complessive di Cosmos DB.
Pratica Ottimale
- Utilizzare le query
SELECT
in quantità limitate, recuperando solo le proprietà necessarie. - Evitare le query cross-partizione fornendo la chiave di partizione nella query.
- Utilizzare filtri su campi indicizzati per ridurre i costi delle query.
Esempio: Recupero del Record del Cliente
var query = new QueryDefinition("SELECT c.firstName, c.lastName FROM Customers c WHERE c.customerId = @customerId")
.WithParameter("@customerId", "12345");
var iterator = container.GetItemQueryIterator<Customer>(query, requestOptions: new QueryRequestOptions
{
PartitionKey = new PartitionKey("12345") // Provide partition key to avoid cross-partition query
});
while (iterator.HasMoreResults)
{
var response = await iterator.ReadNextAsync();
foreach (var customer in response)
{
Console.WriteLine($"{customer.firstName} {customer.lastName}");
}
}
4. Regolazione dei Livelli di Coerenza
I livelli di coerenza definiscono modalità operative specifiche progettate per garantire garanzie legate alla velocità. Ci sono cinque livelli di coerenza (Strong, Bounded Staleness, Session, Consistent Prefix e Eventual) disponibili in Cosmos DB. Ogni livello di coerenza influisce sulla latenza, disponibilità e throughput.
Pratica Ottimale
- Utilizzare la coerenza di sessione per la maggior parte degli scenari per bilanciare prestazioni e coerenza dei dati.
- La coerenza forte garantisce la coerenza dei dati ma aumenta gli RU/s e la latenza.
Esempio: Impostazione del Livello di Coerenza
var cosmosClient = new CosmosClient(
"",
"",
new CosmosClientOptions
{
// Impostare la coerenza su "Session" per prestazioni bilanciate
ConsistencyLevel = ConsistencyLevel.Session
});
Leggi di più sul livello di coerenza qui.
5. Utilizza il Throughput Provisionato (RU/s) e l’Auto-Scale con Saggezza
Il provisioning del throughput è un fattore chiave per raggiungere sia l’efficienza dei costi che le prestazioni ottimali in Azure Cosmos DB. Il servizio ti permette di configurare il throughput in due modi:
- RU/s Fissi: Un livello predefinito e costante di Request Units al secondo (RU/s), adatto per carichi di lavoro con richieste di prestazioni costanti.
- Auto-Scale: Un’opzione dinamica che regola automaticamente il throughput in base alle fluttuazioni del carico di lavoro, fornendo scalabilità e evitando il sovraprovisionamento durante i periodi di bassa attività.
Scegliere il modello di throughput appropriato aiuta a bilanciare efficacemente le esigenze di prestazioni con la gestione dei costi.
Best Practice
- Per carichi di lavoro prevedibili, provisiona manualmente il throughput.
- Utilizza l’auto-scale per carichi di lavoro imprevedibili o burst.
Esempio: Provisioning del Throughput Con Auto-Scale
var throughputProperties = ThroughputProperties.CreateAutoscaleThroughput(maxThroughput: 4000); // Autoscale up to 4000 RU/s
var container = await database.CreateContainerIfNotExistsAsync(new ContainerProperties
{
Id = "autoscaleContainer",
PartitionKeyPath = "/userId"
}, throughputProperties);
Esempio: Impostazione Manuale di RU/s Fissi per Carichi di Lavoro Stabili
var container = await database.CreateContainerIfNotExistsAsync(new ContainerProperties
{
Id = "manualThroughputContainer",
PartitionKeyPath = "/departmentId"
}, throughput: 1000); // Fixed 1000 RU/s
6. Sfrutta il Change Feed per un Elaborazione Efficiente in Tempo Reale
Il feed di modifiche consente di elaborare in tempo reale in base agli eventi catturando automaticamente le modifiche nel database, eliminando la necessità di interrogazioni. Ciò riduce il sovraccarico delle query e migliora l’efficienza.
Migliore Prassi
- Utilizzare il feed di modifiche per scenari in cui le modifiche ai dati in tempo reale devono essere elaborate (ad esempio, analisi in tempo reale, notifiche, avvisi).
Esempio: Lettura dal Feed di Modifiche
var iterator = container.GetChangeFeedIterator(
ChangeFeedStartFrom.Beginning(),
ChangeFeedMode.Incremental);
while (iterator.HasMoreResults)
{
var changes = await iterator.ReadNextAsync();
foreach (var change in changes)
{
Console.WriteLine($"Detected change: {change.Id}");
// Elabora la modifica (ad esempio, attiva l'evento, aggiorna la cache)
}
}
7. Utilizzo del Time-to-Live (TTL) per la Scadenza Automatica dei Dati
Se hai dati che sono rilevanti solo per un periodo limitato, come i log o i dati di sessione, abilitare il Time-to-Live (TTL) in Azure Cosmos DB può aiutare a gestire i costi di archiviazione. Il TTL elimina automaticamente i dati scaduti dopo il periodo di conservazione specificato, eliminando la necessità di pulire manualmente i dati. Questo approccio non solo riduce la quantità di dati archiviati ma garantisce anche che il tuo database sia ottimizzato per l’efficienza dei costi eliminando informazioni obsolete o non necessarie.
Migliore Prassi
- Imposta il TTL per i contenitori in cui i dati dovrebbero scadere automaticamente per ridurre i costi di archiviazione.
Esempio: Impostazione del Time-to-Live (TTL) per i Dati in Scadenza
{
"id": "sessionDataContainer",
"partitionKey": { "paths": ["/sessionId"] },
"defaultTtl": 3600 // 1 hour (3600 seconds)
}
In Cosmos DB, il valore massimo di Time-to-Live (TTL) che può essere impostato è di 365 giorni (1 anno). Ciò significa che i dati possono essere eliminati automaticamente dopo la loro scadenza entro un anno dalla creazione o dall’ultima modifica, a seconda di come si configura il TTL.
8. Evitare le Query Interpartizionamento
Le query interpartizionamento possono aumentare significativamente RU/s e latenza. Per evitarlo:
Pratica Consigliata
- Includere sempre la chiave di partizione nelle query.
- Progettare la strategia di partizionamento per minimizzare l’accesso interpartizionamento.
Esempio: Eseguire Query Con Chiave di Partizione per Evitare Query Interpartizionamento
var query = new QueryDefinition("SELECT * FROM Orders o WHERE o.customerId = @customerId")
.WithParameter("@customerId", "12345");
var resultSetIterator = container.GetItemQueryIterator<Order>(query, requestOptions: new QueryRequestOptions
{
PartitionKey = new PartitionKey("12345")
});
while (resultSetIterator.HasMoreResults)
{
var response = await resultSetIterator.ReadNextAsync();
foreach (var order in response)
{
Console.WriteLine($"Order ID: {order.Id}");
}
}
Conclusione
Questi suggerimenti sono molto efficaci durante lo sviluppo. Implementando una strategia di partizionamento efficace, personalizzando le politiche di indicizzazione, ottimizzando le query, regolando i livelli di coerenza e selezionando i modelli di provisioning del throughput appropriati, è possibile migliorare notevolmente le prestazioni e l’efficienza dell’implementazione di Azure Cosmos DB. Queste ottimizzazioni non solo aumentano la scalabilità ma aiutano anche a gestire i costi fornendo un’esperienza di database ad alte prestazioni.
Source:
https://dzone.com/articles/optimizing-performance-in-azure-cosmos-db