Prestazioni e utilizzo delle risorse - Amazon DocumentDB

Le traduzioni sono generate tramite traduzione automatica. In caso di conflitto tra il contenuto di una traduzione e la versione originale in Inglese, quest'ultima prevarrà.

Prestazioni e utilizzo delle risorse

Questa sezione fornisce domande e soluzioni per problemi di diagnostica comuni nelle distribuzioni di Amazon DocumentDB. Gli esempi forniti utilizzano la shell Mongo e si riferiscono a una singola istanza. Per trovare un endpoint dell'istanza, consulta Comprendere gli endpoint di Amazon DocumentDB.

Come posso determinare il numero di operazioni di inserimento, aggiornamento ed eliminazione eseguite sulla mia raccolta tramite l'API Mongo?

Per visualizzare il numero di operazioni di inserimento, aggiornamento ed eliminazione eseguite su una determinata raccolta, esegui il seguente comando su quella raccolta:

db.collection.stats()

L'output di questo comando descrive quanto segue nel suo opCounters campo:

  • numDocsIns- Il numero di documenti inseriti in questa raccolta. Ciò include i documenti inseriti utilizzando i insertMany comandi insert and, nonché i documenti inseriti da un upsert.

  • numDocsUpd- Il numero di aggiornamenti dei documenti in questa raccolta. Ciò include i documenti aggiornati utilizzando i findAndModify comandi update and.

  • numDocsDel- Il numero di documenti eliminati da questa raccolta. Sono inclusi i documenti eliminati utilizzando i findAndModify comandi deleteOne deleteManyremove,, e.

  • LastReset: l'ora in cui questi contatori sono stati reimpostati l'ultima volta. Le statistiche fornite da questo comando vengono ripristinate all'avvio/arresto del cluster o all'aumento/riduzione dell'istanza.

Di seguito è riportato un esempio di output dell'esecuzione. db.collection.stats()

{ "ns" : "db.test", "count" : ..., "size" : ..., "avgObjSize" : ..., "storageSize" : ..., "capped" : false, "nindexes" : ..., "totalIndexSize" : ..., "indexSizes" : { "_id_" : ..., "x_1" : ... }, "collScans" : ..., "idxScans" : ..., "opCounter" : { "numDocsIns" : ..., "numDocsUpd" : ..., "numDocsDel" : ... }, "cacheStats" : { "collBlksHit" : ..., "collBlksRead" : .., "collHitRatio" : ..., "idxBlksHit" : ..., "idxBlksRead" : ..., "idxHitRatio" : ... }, "lastReset" : "2022-09-02 19:41:40.471473+00", "ok" : 1, "operationTime" : Timestamp(1662159707, 1) }

Questo comando stats deve essere usato quando si visualizzano contatori specifici della raccolta per le operazioni di inserimento, aggiornamento ed eliminazione tramite l'API Mongo. Un altro modo per visualizzare i contatori delle operazioni specifici della raccolta consiste nell'abilitare il controllo DML. Il numero di operazioni di inserimento, aggiornamento ed eliminazione su tutte le raccolte durante intervalli di un minuto può essere visualizzato in. Monitoraggio di Amazon DocumentDB con CloudWatch

Come posso analizzare le prestazioni della cache?

L'analisi delle prestazioni della cache può fornire informazioni sull'efficienza del recupero dei dati e sulle prestazioni del sistema e si basa sulla quantità di dati letti dal disco rispetto alla cache. Forniamo statistiche sulla cache sul numero di accessi alla cache (dati letti dalla cache) e errori di cache (dati che non si trovano nella cache e letti dal disco) per fornire informazioni sulle prestazioni della cache. Le statistiche della cache per una raccolta specifica possono essere trovate eseguendo il seguente comando su quella raccolta:

db.collection.stats()

I valori nel cacheStats campo nell'output di questo comando forniscono le statistiche della cache per la raccolta e le statistiche totali della cache per gli indici creati nella raccolta. Queste statistiche sono elencate di seguito:

  • collBlksHit- Il numero di blocchi letti dalla cache durante le operazioni su questa raccolta.

  • collBlksRead- Il numero di blocchi letti dal disco (cache mancante) durante le operazioni su questa raccolta.

  • collHitRatio- Il rapporto di accesso alla cache per questa raccolta (100 * [collBlksHit / (collBlksHit + collBlksRead)]).

  • idxBlksHit- Il numero di blocchi letti dalla cache per ogni indice creato su questa raccolta.

  • idxBlksRead- Il numero di blocchi letti dal disco (mancanti nella cache) per ogni indice creato su questa raccolta.

  • idxHitRatio- Il rapporto di accessi alla cache per gli indici creati su questa raccolta (). 100 * [idxBlksHit / (idxBlksHit + idxBlksRead)]

  • lastReset- L'ora in cui queste statistiche sono state reimpostate l'ultima volta. Le statistiche fornite da db.collection.stats() vengono reimpostate all'avvio/arresto del cluster o all'aumento/riduzione dell'istanza.

Utilizzando il comando è inoltre possibile trovare una suddivisione dei idxBlksRead campi idxBlksHit e per ogni indice. indexStats Le statistiche sulla cache specifiche dell'indice possono essere trovate eseguendo il comando seguente:

db.collection.aggregate([{$indexStats:{}}]).pretty()

Per ogni indice, nel cacheStats campo sono disponibili le seguenti statistiche sulla cache:

  • blksHit- Il numero di blocchi letti dalla cache per questo indice.

  • blksRead- Il numero di blocchi letti dal disco per questo indice.

  • blksHitRatio- Il rapporto di accesso alla cache arrotondato a quattro cifre decimali, calcolato da. 100 * [blksHit / (blksHit + blksRead)]

Come posso trovare e terminare le query bloccate o dalla prolungata esecuzione?

Le query degli utenti possono essere eseguite lentamente a causa di un piano di query non ottimale o possono essere bloccate a causa di conflitti tra risorse.

Per trovare le query con esecuzione prolungata che rallentano a causa di un piano di query non ottimale o le query bloccate a causa di conflitti tra risorse, utilizza il comando currentOp. Puoi applicare filtri al comando per ridurre l'elenco delle query pertinenti da terminare. È necessario che opid sia associato alla query con esecuzione prolungata per poterla terminare.

La query seguente utilizza il comando currentOp per elencare tutte le query bloccate o in esecuzione per più di 10 secondi.

db.adminCommand({ aggregate: 1, pipeline: [ {$currentOp: {}}, {$match: {$or: [ {secs_running: {$gt: 10}}, {WaitState: {$exists: true}}]}}, {$project: {_id:0, opid: 1, secs_running: 1}}], cursor: {} });

Quindi, puoi restringere la query per trovare l'opid di una query in esecuzione per più di 10 secondi e terminarla.

Per trovare e terminare una query in esecuzione da più di 10 secondi
  1. Trovare l'opid della query.

    db.adminCommand({ aggregate: 1, pipeline: [ {$currentOp: {}}, {$match: {$or: [{secs_running: {$gt: 10}}, {WaitState: {$exists: true}}]}}], cursor: {} });

    L'aspetto dell'output di questa operazione è simile al seguente (formato JSON).

    { "waitedMS" : NumberLong(0), "cursor" : { "firstBatch" : [ { "opid" : 24646, "secs_running" : 12 } ], "id" : NumberLong(0), "ns" : "admin.$cmd" }, "ok" : 1 }
  2. Terminare la query utilizzando l'operazione killOp.

    db.adminCommand({killOp: 1, op: 24646});

Come posso visualizzare un piano di query e ottimizzare una query?

Il rallentamento dell'elaborazione di una query può essere dovuto a un'esecuzione che richiede una scansione completa della raccolta per selezionare i documenti pertinenti. Talvolta, creare indici appropriati consente di accelerare l'esecuzione di una query. Per rilevare questo tipo di scenario e stabilire i campi per cui creare degli indici, puoi usare il comando explain.

Nota

Amazon DocumentDB emula l'API MongoDB 3.6 su un motore di database appositamente progettato che utilizza un sistema di storage distribuito, con tolleranza ai guasti e riparazione automatica. Di conseguenza, i piani di interrogazione e l'output di explain() possono differire tra Amazon DocumentDB e MongoDB. I clienti che desiderano il controllo sul piano di query possono utilizzare l'operatore $hint per applicare la selezione di un indice preferito.

Esegui la query che vuoi ottimizzare con il comando explain come segue.

db.runCommand({explain: {<query document>}})

Di seguito è riportato un esempio di operazione.

db.runCommand({explain:{ aggregate: "sample-document", pipeline: [{$match: {x: {$eq: 1}}}], cursor: {batchSize: 1}} });

L'aspetto dell'output di questa operazione è simile al seguente (formato JSON).

{ "queryPlanner" : { "plannerVersion" : 1, "namespace" : "db.test", "winningPlan" : { "stage" : "COLLSCAN" } }, "serverInfo" : { "host" : "...", "port" : ..., "version" : "..." }, "ok" : 1 }

L'output precedente indica che la fase $match richiede la scansione delle raccolte complete e di verificare che il campo "x" di ciascun documento corrisponda a 1. Se la raccolta annovera molti documenti, la sua scansione e, di conseguenza, l'elaborazione completa della query sono molto lente. La presenza di "COLLSCAN" nell'output del comando explain indica che le prestazioni della query possono migliorare creando indici appropriati.

In questo esempio, la query verifica se il campo "x" è uguale a 1 in tutti i documenti. Pertanto, la creazione di un indice sul campo "x" consente alla query di evitare la scansione completa della raccolta e di utilizzare l'indice per restituire i documenti pertinenti in meno tempo.

Dopo aver creato un indice sul campo "x", l'output di explain è il seguente.

{ "queryPlanner" : { "plannerVersion" : 1, "namespace" : "db.test", "winningPlan" : { "stage" : "IXSCAN", "indexName" : "x_1", "direction" : "forward" } }, "serverInfo" : { "host" : "...", "port" : ..., "version" : "..." }, "ok" : 1 }

La creazione di un indice sul campo "x" ha permesso alla fase $match di avviare una scansione dell'indice e ridurre il numero di documenti per cui valutare il predicato "x = 1".

Per raccolte di piccole dimensioni, il processore di query Amazon DocumentDB può scegliere di non utilizzare un indice se i miglioramenti delle prestazioni sono trascurabili.

Come posso visualizzare un piano di query in cluster elastici?

Per esaminare un piano di query in cluster elastici, usa il explain comando. Di seguito è riportato un esempio di explain operazione su una query di ricerca destinata a una raccolta frammentata:

db.runCommand( { explain: { find: "cities", filter: {"name": "Seoul"}} } )
Nota

Amazon DocumentDB emula MongoDB su un motore di database creato appositamente. Di conseguenza, i piani di interrogazione e l'output di explain() possono differire tra Amazon DocumentDB e MongoDB. Puoi controllare il piano di interrogazione utilizzando l'$hintoperatore per imporre la selezione di un indice preferito.

L'output di questa operazione può essere simile al seguente (formato JSON):

{ "queryPlanner" : { "elasticPlannerVersion" : 1, "winningPlan" : { "stage" : "SINGLE_SHARD", "shards" : [ { "plannerVersion" : 1, "namespace" : "population.cities", "winningPlan" : { "stage" : "SHARD_MERGE", "shards" : [ { "shardName" : "f2cf5cfd-fe9c-40ca-b4e5-298ca0d11111", "plannerVersion" : 1, "namespace" : "population.cities", "winningPlan" : { "stage" : "PARTITION_MERGE", "inputStages" : [ { "stage" : "COLLSCAN", "partitionCount" : 21 } ] } }, { "shardName" : "8f3f80e2-f96c-446e-8e9d-aab8c7f22222", "plannerVersion" : 1, "namespace" : "population.cities", "winningPlan" : { "stage" : "PARTITION_MERGE", "inputStages" : [ { "stage" : "COLLSCAN", "partitionCount" : 21 } ] } }, { "shardName" : "32c5a06f-1b2b-4af1-8849-d7c4a033333", "plannerVersion" : 1, "namespace" : "population.cities", "winningPlan" : { "stage" : "PARTITION_MERGE", "inputStages" : [ { "stage" : "COLLSCAN", "partitionCount" : 22 } ] } } ] }, "shardName" : "32c5a06f-1b2b-4af1-8849-d7c4a0f3fb58" } ] } }, "serverInfo" : { "host" : "example-4788267630.us-east-1.docdb-elastic.amazonaws.com:27017", "version" : "5.0.0" }, "ok" : 1, "operationTime" : Timestamp(1695097923, 1) }

L'output precedente mostra il piano di interrogazione per la find query su un cluster a tre shard. Ogni shard ha più partizioni di dati che possono avere fasi di input diverse. In questo esempio, viene eseguita una «COLLSCAN» (una scansione della raccolta) su tutte le partizioni prima che i risultati vengano uniti nella fase «PARTITION_MERGE» all'interno di ogni shard. I risultati degli shard vengono quindi uniti nella fase» SHARD_MERGE» prima di essere rispediti al client.

Come posso creare un elenco di tutte le operazioni in esecuzione su un'istanza?

In qualità di utente o utente principale, spesso si desidera elencare tutte le operazioni correnti in esecuzione su un'istanza per scopi di diagnostica e risoluzione dei problemi. Per ulteriori informazioni sulla gestione degli utenti, consulta Gestione degli utenti Amazon DocumentDB.

Con la mongo shell, puoi utilizzare la seguente query per elencare tutte le operazioni in esecuzione su un'istanza Amazon DocumentDB.

db.adminCommand({currentOp: 1, $all: 1});

La query restituisce l'elenco completo di tutte le query e le attività interne del sistema attualmente operative nell'istanza.

L'aspetto dell'output di questa operazione è simile al seguente (formato JSON).

{ "inprog" : [ { "desc" : "INTERNAL" }, { "desc" : "TTLMonitor", "active" : false }, { "client" : ..., "desc" : "Conn", "active" : true, "killPending" : false, "opid" : 195, "ns" : "admin.$cmd", "command" : { "currentOp" : 1, "$all" : 1 }, "op" : "command", "$db" : "admin", "secs_running" : 0, "microsecs_running" : NumberLong(68), "clientMetaData" : { "application" : { "name" : "MongoDB Shell" }, "driver" : { ... }, "os" : { ... } } }, { "desc": "GARBAGE_COLLECTION", "garbageCollection": { "databaseName": "testdb", "collectionName": "testCollectionA" }, "secs_running": 3, "microsecs_running": NumberLong(3123456) }, { "desc": "GARBAGE_COLLECTION", "garbageCollection": { "databaseName": "testdb", "collectionName": "testCollectionB" }, "secs_running": 4, "microsecs_running": NumberLong(4123456) } ], "ok" : 1 }

Di seguito sono riportati i valori validi per il campo "desc".

  • INTERNAL— Attività interne al sistema come la pulizia del cursore o le attività di pulizia degli utenti non aggiornate.

  • TTLMonitor— Il thread di monitoraggio Time to Live (TTL). Il suo stato di esecuzione si riflette nel campo "active".

  • GARBAGE_COLLECTION— Il thread interno del Garbage Collector.

  • CONN— La richiesta dell'utente.

  • CURSOR— L'operazione è un cursore inattivo che attende che l'utente chiami il comando «getMore» per ottenere il successivo batch di risultati. In questo stato, il cursore consuma memoria, ma non consuma alcuna elaborazione.

L'output precedente elenca, inoltre, tutte le query degli utenti in esecuzione nel sistema. Ogni query viene eseguita in un contesto formato da un database e una raccolta, detto spazio dei nomi. Lo spazio dei nomi di una query è disponibile nel campo "ns".

A volte è necessario elencare tutte le query degli utenti in esecuzione in un determinato spazio dei nomi. Pertanto, l'output precedente deve essere filtrato in base al campo "ns". Di seguito è riportato un esempio di query per filtrare l'output. La query elenca tutte le query degli utenti attualmente in esecuzione nel database "db" e nella raccolta "test" (ovvero lo spazio dei nomi "db.test").

db.adminCommand({aggregate: 1, pipeline: [{$currentOp: {allUsers: true, idleConnections: true}}, {$match: {ns: {$eq: "db.test"}}}], cursor: {} });

In qualità di utente principale del sistema, puoi visualizzare le domande di tutti gli utenti e anche tutte le attività interne del sistema. Tutti gli altri utenti, invece, possono vedere solo le rispettive query.

Se il numero totale di query e attività di sistema non rientra nelle dimensioni predefinite del cursore di batch, la shell mongo genera automaticamente un oggetto iteratole 'it' che consente di visualizzare il resto dei risultati. Bisogna mantenere in esecuzione il comando 'it' fino a esaurimento dei risultati.

Come faccio a sapere quando una query sta facendo progressi?

Le query degli utenti possono essere eseguite lentamente a causa di un piano di query non ottimale o possono essere bloccate a causa di conflitti tra risorse. Il debug di questo tipo di query è un processo in più fasi che può richiedere di ripetere più volte una stessa operazione.

Innanzitutto, ai fini del debug, occorre elencare tutte le query bloccate o dall'esecuzione prolungata. La query seguente elenca tutte le query utente che sono state in esecuzione per più di 10 secondi o che sono in attesa di risorse.

db.adminCommand({aggregate: 1, pipeline: [{$currentOp: {}}, {$match: {$or: [{secs_running: {$gt: 10}}, {WaitState: {$exists: true}}]}}, {$project: {_id:0, opid: 1, secs_running: 1, WaitState: 1, blockedOn: 1, command: 1}}], cursor: {} });

Ripeti periodicamente la query precedente per determinare se l'elenco delle query cambia e per identificare le query bloccate o con esecuzione prolungata.

L'eventuale presenza del campo WaitState nel documento di output della query d'interesse indica che il motivo alla base del blocco o della lenta esecuzione della query è un conflitto tra le risorse. Tale conflitto potrebbe attribuirsi all'I/O, alle attività interne di sistema o ad altre query dell'utente.

L'aspetto dell'output di questa operazione è simile al seguente (formato JSON).

{ "waitedMS" : NumberLong(0), "cursor" : { "firstBatch" : [ { "opid" : 201, "command" : { "aggregate" : ... }, "secs_running" : 208, "WaitState" : "IO" } ], "id" : NumberLong(0), "ns" : "admin.$cmd" }, "ok" : 1 }

L'I/O potrebbe rivelarsi inefficace in presenza di molte query afferenti a raccolte diverse e in esecuzione simultanea sulla stessa istanza o se l'istanza dovesse risultare troppo piccola per il set di dati in cui la query viene eseguita. Se le query sono di sola lettura, puoi mitigare la situazione precedente separando le query per ogni raccolta tra repliche separate. In caso di aggiornamenti simultanei in raccolte diverse o quando l'istanza è troppo piccola per il set di dati, la soluzione di mitigazione consiste nel ridimensionare l'istanza.

Se il conflitto tra le risorse è causato da query di altri utenti, il campo "blockedOn" nel documento di output presenta il valore "opid" della query responsabile del problema. Avvaliti della voce "opid" e segui la concatenazione dei campi "WaitState" e "blockedOn" di tutte le query per individuare la query all'inizio della catena.

Se l'attività in testa alla catena è un'operazione interna, la soluzione di mitigazione consiste nel terminare la query ed eseguirla nuovamente in un secondo momento.

Di seguito è riportato un output di esempio in cui la query di ricerca è bloccata su un blocco di raccolta di proprietà di un'altra attività.

{ "inprog" : [ { "client" : "...", "desc" : "Conn", "active" : true, "killPending" : false, "opid" : 75, "ns" : "...", "command" : { "find" : "...", "filter" : { } }, "op" : "query", "$db" : "test", "secs_running" : 9, "microsecs_running" : NumberLong(9449440), "threadId" : 24773, "clientMetaData" : { "application" : { "name" : "MongoDB Shell" }, "driver" : { ... }, "os" : { ... } }, "WaitState" : "CollectionLock", "blockedOn" : "INTERNAL" }, { "desc" : "INTERNAL" }, { "client" : "...", ... "command" : { "currentOp" : 1 }, ... } ], "ok" : 1 }

Se "WaitState" presenta i valori "Latch", "SystemLock", "BufferLock", "BackgroundActivity" o "Other", il conflitto tra risorse è originato da attività interne di sistema. Se la situazione persiste per un lungo periodo di tempo, l'unica soluzione di mitigazione consiste nel terminare la query ed eseguirla nuovamente in un secondo momento.

Come faccio a determinare il motivo per cui un sistema funziona improvvisamente lentamente?

Di seguito sono elencati alcuni motivi comuni del rallentamento del sistema:

  • Eccessivi conflitti delle risorse tra query simultanee

  • Il numero di query simultanee attive aumenta nel tempo

  • Attività interne di sistema, ad esempio "GARBAGE_COLLECTION"

Per monitorare l'utilizzo del sistema nel tempo, esegui periodicamente la seguente query "currentOp" e trasferisci i risultati su un archivio esterno. La query conta le query e operazioni nei vari spazi dei nomi presenti nel sistema. Puoi analizzare i risultati relativi all'utilizzo del sistema per stabilire il carico del sistema e prendere le decisioni appropriate.

db.adminCommand({aggregate: 1, pipeline: [{$currentOp: {allUsers: true, idleConnections: true}}, {$group: {_id: {desc: "$desc", ns: "$ns", WaitState: "$WaitState"}, count: {$sum: 1}}}], cursor: {} });

Questa query restituisce un'aggregazione delle query eseguite nei vari spazi dei nomi e di tutte le attività interne di sistema, nonché il numero univoco degli eventuali stati di attesa per spazio dei nomi.

L'aspetto dell'output di questa operazione è simile al seguente (formato JSON).

{ "waitedMS" : NumberLong(0), "cursor" : { "firstBatch" : [ { "_id" : { "desc" : "Conn", "ns" : "db.test", "WaitState" : "CollectionLock" }, "count" : 2 }, { "_id" : { "desc" : "Conn", "ns" : "admin.$cmd" }, "count" : 1 }, { "_id" : { "desc" : "TTLMonitor" }, "count" : 1 } ], "id" : NumberLong(0), "ns" : "admin.$cmd" }, "ok" : 1 }

L'output precedente annovera due query dell'utente nello spazio dei nomi "db.test" che sono bloccate a causa di un blocco della raccolta, una query nello spazio dei nomi "admin.$cmd" e un'attività "TTLMonitor" interna.

Se l'output indica il blocco di molte query in stato di attesa, consulta Come posso trovare e terminare le query bloccate o dalla prolungata esecuzione?

Come posso determinare la causa dell'elevato utilizzo della CPU su una o più istanze del cluster?

Le sezioni seguenti possono aiutarti a identificare la causa dell'elevato utilizzo della CPU da parte delle istanze. I risultati possono variare a seconda del carico di lavoro.

A seconda del motivo dell'elevato utilizzo della CPU da parte delle istanze, può essere utile eseguire una o più delle operazioni indicate di seguito.

  • Se l'istanza primaria presenta un elevato utilizzo della CPU diversamente dalle istanze di replica, valuta la possibilità di distribuire il traffico di lettura tra le repliche tramite le impostazioni delle preferenze di lettura del client (ad esempio, secondaryPreferred). Per ulteriori informazioni, consulta Connessione ad Amazon DocumentDB come set di repliche.

    L'utilizzo delle repliche per le letture può ottimizzare l'uso delle risorse del cluster consentendo all'istanza primaria di elaborare più traffico di scrittura. Le letture dalle repliche sono consistenti finali.

  • Se l'elevato utilizzo della CPU è il risultato del carico di lavoro di scrittura, la modifica delle dimensioni delle istanze del cluster in un tipo di istanza più grande aumenta il numero di core CPU disponibili per il carico di lavoro. Per ulteriori informazioni, consultare Istanze e Specifiche per la classe di istanza.

  • Se tutte le istanze del cluster presentano un elevato utilizzo della CPU e il carico di lavoro utilizza le repliche per le letture, l'aggiunta di più repliche al cluster aumenta le risorse disponibili per il traffico di lettura. Per ulteriori informazioni, consulta Aggiungere un'istanza Amazon DocumentDB a un cluster.

Come faccio a determinare i cursori aperti su un'istanza?

Quando sei connesso a un'istanza Amazon DocumentDB, puoi usare il comando db.runCommand("listCursors") per elencare i cursori aperti su quell'istanza. Esiste un limite massimo di 4.560 cursori attivi aperti in un dato momento su una determinata istanza di Amazon DocumentDB, a seconda del tipo di istanza. Si consiglia generalmente di chiudere i cursori che non sono più in uso in quanto utilizzano risorse su un'istanza e prevedono un limite massimo. Vedi per i limiti specificiQuote e limiti di Amazon DocumentDB.

db.runCommand("listCursors")

Come posso determinare la versione corrente del motore Amazon DocumentDB?

Per determinare la versione corrente del motore Amazon DocumentDB, esegui il comando seguente.

db.runCommand({getEngineVersion: 1})

L'aspetto dell'output di questa operazione è simile al seguente (formato JSON).

{ "engineVersion" : "2.x.x", "ok" : 1 }
Nota

La versione del motore per Amazon DocumentDB 3.6 è 1.x.x e la versione del motore per Amazon DocumentDB 4.0 è 2.x.x.

In che modo posso analizzare l'utilizzo degli indici e identificare gli indici non utilizzati?

Per identificare gli indici per una determinata raccolta, eseguire il comando seguente:

db.collection.getIndexes()

Per analizzare la quantità di indici utilizzati durante le operazioni eseguite sulle raccolte, è possibile utilizzare i comandi collStats andindexStats. Per visualizzare il numero totale di scansioni eseguite utilizzando gli indici (index scans) rispetto al numero di scansioni eseguite senza un indice (collection scans), esegui il comando seguente:

db.collection.stats()

L'output di questo comando include i seguenti valori:

  • idxScans- Il numero di scansioni eseguite su questa raccolta utilizzando un indice.

  • collScans- Il numero di scansioni eseguite su questa raccolta senza utilizzare un indice. Queste scansioni avrebbero comportato la ricerca dei documenti della raccolta uno alla volta.

  • lastReset- L'ora in cui questi contatori sono stati azzerati l'ultima volta. Le statistiche fornite da questo comando vengono ripristinate all'avvio/arresto del cluster o all'aumento/riduzione dell'istanza.

Un'analisi dettagliata dell'utilizzo di ciascun indice è disponibile nell'output del comando seguente. È consigliabile identificare e rimuovere regolarmente gli indici non utilizzati per migliorare le prestazioni e ridurre i costi, in quanto elimina l'elaborazione, lo storage e gli I/O non necessari utilizzati per la manutenzione degli indici.

db.collection.aggregate([{$indexStats:{}}]).pretty()

L'output di questo comando fornisce i seguenti valori per ogni indice creato nella raccolta:

  • ops- Il numero di operazioni che hanno utilizzato l'indice. Se il carico di lavoro è in esecuzione per un periodo sufficientemente lungo e si è certi che il carico di lavoro è in uno stato costante, un valore ops pari a zero indica che l'indice non viene utilizzato affatto.

  • numDocsRead- Il numero di documenti letti durante le operazioni che utilizzano questo indice.

  • since- Il periodo trascorso da quando Amazon DocumentDB ha iniziato a raccogliere statistiche sull'utilizzo dell'indice, che in genere è il valore dall'ultima operazione di riavvio o manutenzione del database.

  • size- La dimensione di questo indice in byte.

L'esempio seguente è un esempio di output ottenuto dall'esecuzione del comando precedente:

{ "name" : "_id_", "key" : { "_id" : 1 }, "host" : "example-host.com:12345", "size" : NumberLong(...), "accesses" : { "ops" : NumberLong(...), "docsRead" : NumberLong(...), "since" : ISODate("...") }, "cacheStats" : { "blksRead" : NumberLong(...), "blksHit" : NumberLong(...), "hitRatio" : ... } } { "name" : "x_1", "key" : { "x" : 1 }, "host" : "example-host.com:12345", "size" : NumberLong(...), "accesses" : { "ops" : NumberLong(...), "docsRead" : NumberLong(...), "since" : ISODate("...") }, "cacheStats" : { "blksRead" : NumberLong(...), "blksHit" : NumberLong(...), "hitRatio" : ... } }

Per determinare la dimensione complessiva dell'indice per una raccolta, eseguire il comando seguente:

db.collection.stats()

Per eliminare un indice inutilizzato, eseguire il comando seguente:

db.collection.dropIndex("indexName")

Come posso identificare gli indici mancanti?

Puoi utilizzare il profiler Amazon DocumentDB per registrare le query lente. Una query che viene visualizzata ripetutamente nel log di query lento potrebbe indicare che è necessario un indice aggiuntivo per migliorare le prestazioni della query.

È possibile identificare le opportunità di indici utili cercando query a esecuzione prolungata con una o più fasi che eseguono almeno una fase COLLSCAN, il che significa che la fase di query deve leggere tutti i documenti della raccolta al fine di fornire una risposta alla query.

Nell'esempio seguente viene illustrata una query su un insieme di corse in taxi eseguite su una raccolta di grandi dimensioni.

db.rides.count({"fare.totalAmount":{$gt:10.0}}))

Per eseguire questo esempio, la query doveva eseguire una scansione della raccolta (cioè leggere ogni singolo documento nella raccolta) poiché non vi è alcun indice sul campo fare.totalAmount. L'output del profiler Amazon DocumentDB per questa query è simile al seguente:

{ ... "cursorExhausted": true, "nreturned": 0, "responseLength": 0, "protocol": "op_query", "millis": 300679, "planSummary": "COLLSCAN", "execStats": { "stage": "COLLSCAN", "nReturned": "0", "executionTimeMillisEstimate": "300678.042" }, "client": "172.31.5.63:53878", "appName": "MongoDB Shell", "user": "example" }

Per velocizzare la query in questo esempio, si desidera creare un indice su fare.totalAmount, come illustrato di seguito.

db.rides.createIndex( {"fare.totalAmount": 1}, {background: true} )
Nota

Gli indici creati in primo piano (ovvero se l'opzione {background:true} non è stata fornita durante la creazione dell'indice) assumono un blocco di scrittura esclusivo, che impedisce alle applicazioni di scrivere dati nella raccolta fino al completamento della compilazione dell'indice. Tenere presente questo potenziale impatto durante la creazione di indici nei cluster di produzione. Quando si creano indici, si consiglia di impostare {background:true}.

In generale, si desidera creare indici su campi con elevata cardinalità (ad esempio, un numero elevato di valori univoci). La creazione di un indice su un campo con bassa cardinalità può comportare un indice di grandi dimensioni che non viene utilizzato. L'ottimizzatore di query di Amazon DocumentDB considera la dimensione complessiva della raccolta e la selettività degli indici durante la creazione di un piano di query. In alcuni momenti, l'elaboratore di query selezionerà un COLLSCAN anche se è presente un indice. Ciò accade quando l'elaboratore di query stima che l'utilizzo dell'indice non produrrà un vantaggio in termini di prestazioni rispetto alla scansione dell'intera raccolta. Se si desidera forzare l'elaboratore di query affinché utilizzi un particolare indice, è possibile ricorrere all'hint() come illustrato di seguito.

db.collection.find().hint("indexName")

Riepilogo delle domande utili

Le seguenti query possono essere utili per monitorare le prestazioni e l'utilizzo delle risorse in Amazon DocumentDB.

  • Utilizza il seguente comando per visualizzare le statistiche su una raccolta specifica, inclusi contatori operativi, statistiche sulla cache, statistiche sugli accessi e statistiche sulle dimensioni:

    db.collection.stats()
  • Utilizzate il comando seguente per visualizzare le statistiche su ogni indice creato in una raccolta, comprese le dimensioni dell'indice, le statistiche sulla cache specifiche dell'indice e le statistiche sull'utilizzo dell'indice:

    db.collection.aggregate([{$indexStats:{}}]).pretty()
  • Utilizza la seguente query per elencare tutte le attività.

    db.adminCommand({currentOp: 1, $all: 1});
  • Il codice seguente elenca tutte le query bloccate o con esecuzione prolungata.

    db.adminCommand({aggregate: 1, pipeline: [{$currentOp: {}}, {$match: {$or: [{secs_running: {$gt: 10}}, {WaitState: {$exists: true}}]}}, {$project: {_id:0, opid: 1, secs_running: 1, WaitState: 1, blockedOn: 1, command: 1}}], cursor: {} });
  • Il codice seguente termina una query.

    db.adminCommand({killOp: 1, op: <opid of running or blocked query>});
  • Utilizza il codice seguente per ottenere una visualizzazione aggregata dello stato del sistema.

    db.adminCommand({aggregate: 1, pipeline: [{$currentOp: {allUsers: true, idleConnections: true}}, {$group: {_id: {desc: "$desc", ns: "$ns", WaitState: "$WaitState"}, count: {$sum: 1}}}], cursor: {} });