Rendimiento y utilización de recursos - Amazon DocumentDB

Las traducciones son generadas a través de traducción automática. En caso de conflicto entre la traducción y la version original de inglés, prevalecerá la version en inglés.

Rendimiento y utilización de recursos

En esta sección se proporcionan preguntas y soluciones para los problemas de diagnóstico frecuentes en las implementaciones de Amazon DocumentDB. Los ejemplos que se proporcionan utilizan el intérprete de comandos de mongo y se limitan a una instancia individual. Para encontrar un punto de conexión de instancia, consulte Descripción de los puntos de conexión de Amazon DocumentDB.

¿Cómo determino el número de operaciones de inserción, actualización y eliminación realizadas en mi colección a través de la API de Mongo?

Para ver el número de operaciones de inserción, actualización y eliminación realizadas en una colección determinada, ejecute el siguiente comando en esa colección:

db.collection.stats()

La salida de este comando describe lo siguiente en su campo opCounters:

  • numDocsIns- El número de documentos insertados en esta colección. Incluye los documentos insertados mediante los comandos insert y insertMany, así como los documentos insertados mediante actualizar o insertar.

  • numDocsUpd- El número de documentos actualizados en esta colección. Incluye los documentos actualizados mediante los comandos update y findAndModify.

  • numDocsDel- El número de documentos eliminados de esta colección. Incluye los documentos eliminados mediante los comandos deleteOne, deleteMany, remove y findAndModify.

  • lastReset: hora a la que se restablecieron estos contadores por última vez. Las estadísticas proporcionadas por este comando se restablecen al iniciar o detener el clúster o al escalar la instancia en dirección ascendente o descendente.

A continuación, se muestra una salida de ejemplo de ejecución de 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) }

Este comando de estadística debe usarse al ver los contadores específicos de la colección para las operaciones de inserción, actualización y eliminación a través de la API de Mongo. Otra forma de ver los contadores de operaciones específicas de una colección es habilitar la auditoría de DML. Se puede ver en Monitorización de Amazon DocumentDB con CloudWatch el número de operaciones de inserción, actualización y eliminación en todas las colecciones durante intervalos de un minuto.

¿Cómo analizo el rendimiento de la memoria caché?

El análisis del rendimiento de la memoria caché puede proporcionar información sobre la eficiencia de la recuperación de datos y el rendimiento del sistema, y se basa en la cantidad de datos que se leen del disco en comparación con la memoria caché. Proporcionamos estadísticas de la memoria caché sobre el número de visitas a la memoria caché (datos leídos de la memoria caché) y pérdidas de memoria caché (datos que no se encuentran en la memoria caché y se leen en el disco) para obtener información sobre el rendimiento de la memoria caché. Las estadísticas de la memoria caché de una colección específica se pueden encontrar ejecutando el siguiente comando en esa colección:

db.collection.stats()

Los valores del campo cacheStats del resultado de este comando proporcionan las estadísticas de la memoria caché de la colección, así como las estadísticas de la memoria caché totales de los índices creados en la colección. Estas estadísticas se muestran a continuación:

  • collBlksHit: el número de bloques leídos de la memoria caché durante las operaciones de esta colección.

  • collBlksRead: el número de bloques leídos del disco (pérdidas de memoria caché) durante las operaciones de esta colección.

  • collHitRatio: la proporción de aciertos de la memoria caché de esta colección (100 * [collBlksHit / (collBlksHit + collBlksRead)]).

  • idxBlksHit: el número de bloques leídos de la memoria caché para cualquier índice creado en esta colección.

  • idxBlksRead: el número de bloques leídos del disco (pérdidas de memoria caché) para cualquier índice creado en esta colección.

  • idxHitRatio: la proporción de aciertos de la memoria caché creados en esta colección (100 * [idxBlksHit / (idxBlksHit + idxBlksRead)]).

  • lastReset: hora a la que se restablecieron estas estadísticas por última vez. Las estadísticas proporcionadas por db.collection.stats() se restablecen al iniciar o detener el clúster o al escalar la instancia en dirección ascendente o descendente.

También se puede encontrar un desglose de los campos idxBlksHit y idxBlksRead de cada índice mediante el comando indexStats. Puede encontrar las estadísticas de memoria caché específicas del índice ejecutando el siguiente comando:

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

Para cada índice, se encuentran las siguientes estadísticas de memoria caché en el campo cacheStats:

  • blksHit: el número de bloques leídos de la memoria caché para este índice.

  • blksRead: el número de bloques leídos del disco para este índice.

  • blksHitRatio: la proporción de aciertos de la memoria caché redondeada a cuatro decimales, calculada mediante 100 * [blksHit / (blksHit + blksRead)].

¿Cómo puedo encontrar y terminar las consultas que tardan mucho en ejecutarse o se bloquean?

Es posible que las consultas del usuario se ejecuten lentamente debido a que el plan de consultas es inadecuado o a que se bloquean debido a la contención de recursos.

Para buscar consultas de ejecución prolongada que se ralenticen a causa de un plan de consultas inadecuado o consultas que se bloquean debido a la contención de recursos, utilice el comando currentOp. Puede filtrar el comando para acotar la lista de las consultas relevantes que deben terminarse. Debe tener asociado opid a la consulta de ejecución prolongada para poder terminarla.

En la siguiente consulta, se utiliza el comando currentOp para ver todas las consultas que están bloqueadas o que se llevan ejecutando durante más de 10 segundos.

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

A continuación, puede limitar la consulta para encontrar el opid de una consulta que lleva ejecutándose durante más de 10 segundos y terminarla.

Para encontrar y terminar una consulta que lleva ejecutándose durante más de 10 segundos
  1. Busque el opid de la consulta.

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

    La salida de esta operación será similar a lo que se indica a continuación (formato JSON).

    { "waitedMS" : NumberLong(0), "cursor" : { "firstBatch" : [ { "opid" : 24646, "secs_running" : 12 } ], "id" : NumberLong(0), "ns" : "admin.$cmd" }, "ok" : 1 }
  2. Termine la consulta con la operación killOp.

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

¿Cómo puedo ver un plan de consulta y optimizar una consulta?

Si una consulta se ejecuta lentamente, podría deberse a que la ejecución de la consulta requiere un examen completo de la colección para elegir los documentos pertinentes. A veces, la creación de los índices adecuados permite que la consulta se ejecute con mayor rapidez. Para detectar este escenario y decidir en qué campos se deben crear los índices, utilice el comando explain.

nota

Amazon DocumentDB emula la API MongoDB 3.6 en un motor de base de datos personalizada específicamente que utiliza un sistema de almacenamiento distribuido, tolerante a fallos y de recuperación automática. Como resultado, los planes de consulta y la salida de explain() pueden diferir entre Amazon DocumentDB y MongoDB. Los clientes que deseen controlar su plan de consulta pueden utilizar el operador $hint para aplicar la selección de un índice preferido.

Ejecute la consulta que desee mejorarse en el comando explain del modo siguiente.

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

A continuación se muestra un ejemplo de operación.

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

La salida de esta operación será similar a lo que se indica a continuación (formato JSON).

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

El resultado anterior indica que la etapa $match requiere examinar todas las colecciones y comprobar si el campo "x" de cada documento es igual a 1. Si hay muchos documentos en la colección, el examen de la consulta (y, por tanto, el rendimiento general de la consulta) es muy lento. Por consiguiente, la presencia de "COLLSCAN" en el resultado del comando explain indica que el rendimiento de la consulta se puede mejorar creando los índices adecuados.

En este ejemplo, la consulta comprueba si el campo "x" es igual a 1 en todos los documentos. Por tanto, la creación de un índice en el campo "x" permite que la consulta evite el examen completo de la colección y utilice el índice para devolver los documentos pertinentes antes.

Después de crear un índice en el campo "x", el resultado de explain es el siguiente.

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

La creación de un índice en el campo "x" permite que la etapa $match utilice un análisis de índices para reducir el número de documentos en los que debe evaluarse el predicado "x = 1".

En colecciones pequeñas, el procesador de consultas de Amazon DocumentDB puede optar por no utilizar un índice si las ventajas para el rendimiento son insignificantes.

¿Cómo puedo ver un plan de consultas en clústeres elásticos?

Para examinar un plan de consultas en clústeres elásticos, utilice el comando explain. A continuación, se muestra un ejemplo de operación explain en una consulta de búsqueda dirigida a una colección con partición:

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

Amazon DocumentDB emula MongoDB en un motor de base de datos personalizada. Como resultado, los planes de consulta y la salida de explain() pueden diferir entre Amazon DocumentDB y MongoDB. Los clientes que deseen controlar su plan de consulta pueden utilizar el operador $hint para aplicar la selección de un índice preferido.

La salida de esta operación será similar a lo que se indica a continuación (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) }

El resultado anterior muestra el plan de consulta para la consulta find en un clúster de tres particiones. Cada partición tiene varias particiones de datos que pueden tener diferentes etapas de entrada. En este ejemplo, se ejecuta un “COLLSCAN” (un escaneo de colecciones) en todas las particiones antes de fusionar los resultados en la etapa “PARTITION_MERGE” de cada partición. A continuación, los resultados de las particiones se combinan en la etapa “SHARD_MERGE” antes de enviarlos de vuelta al cliente.

¿Cómo puedo ver todas las operaciones en ejecución en una instancia?

Como usuario o usuario principal, a menudo querrá enumerar todas las operaciones actuales que se están ejecutando en una instancia con fines de diagnóstico y solución de problemas. (Para obtener información acerca de cómo administrar los usuarios, consulte Administración de usuarios de Amazon DocumentDB).

Con el intérprete de comandos de mongo, puede utilizar la siguiente consulta para ver una lista de todas las operaciones en ejecución en una instancia de Amazon DocumentDB.

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

La consulta devuelve la lista completa de todas las consultas del usuario y las tareas internas del sistema que se están realizando actualmente en la instancia.

La salida de esta operación será similar a lo que se indica a continuación (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 }

Los siguientes valores son válidos para el campo "desc":

  • INTERNAL: tareas internas del sistema, como tareas de limpieza del cursor o limpieza de usuarios obsoletos.

  • TTLMonitor: el hilo de supervisión de tiempo de vida (TTL). Su estado de funcionamiento se refleja en el campo "active".

  • GARBAGE_COLLECTION: el subproceso del recolector de elementos no utilizados interno.

  • CONN: la consulta del usuario.

  • CURSOR: la operación consiste en un cursor inactivo que espera a que el usuario ejecute el comando “GetMore” para obtener el siguiente lote de resultados. En este estado, el cursor consume memoria, pero no consume capacidad de cálculo.

El resultado anterior también muestra todas las consultas del usuario que se ejecutan en el sistema. Cada consulta del usuario se ejecuta en el contexto de una base de datos y una colección. La unión de las dos se denomina espacio de nombres. El espacio de nombres de cada consulta del usuario está disponible en el campo "ns".

A veces, es necesario ver una lista de todas las consultas del usuario que se están ejecutando en un determinado espacio de nombres. Por tanto, el resultado anterior debe filtrarse en el campo "ns". A continuación, se muestra una consulta de ejemplo para conseguir el resultado que se va a filtrar. La consulta muestra todas las consultas del usuario que se están ejecutando actualmente en la base de datos "db" y la colección "test" (es decir, el espacio de nombres "db.test").

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

Como usuario principal del sistema, puede ver las consultas de todos los usuarios y también todas las tareas internas del sistema. Los demás usuarios solo pueden ver sus consultas respectivas.

Si el número total de consultas y tareas internas del sistema supera el tamaño del cursor batch predeterminado, el intérprete de comandos de mongo genera automáticamente un objeto de iteración 'it' para ver el resto de los resultados. Siga ejecutando el comando 'it' hasta que se hayan agotado todos los resultados.

¿Cómo sé cuándo una consulta está avanzando?

Es posible que las consultas del usuario se ejecuten lentamente debido a que el plan de consultas es inadecuado o a que se bloquean debido a la contención de recursos. La depuración de estas consultas es un proceso de varios pasos en el que puede ser necesario realizar el mismo paso varias veces.

El primer paso de la depuración es mostrar todas las consultas que tardan mucho tiempo en ejecutarse o que se bloquean. La siguiente consulta muestra todas las consultas del usuario que se han ejecutado durante más de 10 segundos o que están esperando recursos.

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: {} });

Repita la consulta anterior de forma periódica para determinar si la lista de consultas cambia e identificar la consulta de ejecución prolongada o las consultas bloqueadas.

Si el documento de salida de la consulta en cuestión tiene un campo WaitState, indica que la contención de recursos es la razón por la que la consulta tarda mucho en ejecutarse o se bloquea. La contención de recursos puede deberse a operaciones de E/S, tareas internas del sistema u otras consultas del usuario.

La salida de esta operación será similar a lo que se indica a continuación (formato JSON).

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

Las operaciones de E/S pueden producir un cuello de botella si se ejecutan muchas consultas en diferentes colecciones al mismo tiempo en la misma instancia o si la instancia es demasiado pequeña para el conjunto de datos en el que se está ejecutando la consulta. Si las consultas son consultas de solo lectura, puede mitigar la situación anterior separando las consultas de cada colección en réplicas diferentes. En las actualizaciones simultáneas en diferentes colecciones o cuando el tamaño de la instancia es demasiado pequeño para el conjunto de datos, puede mitigarla ampliando la instancia.

Si la contención de recursos se debe a otras consultas del usuario, el campo "blockedOn" del documento de salida contendrá el "opid" de la consulta que afecta a esta consulta. Mediante el "opid", siga la cadena de campos "WaitState" y "blockedOn" de todas las consultas para encontrar la consulta de la parte superior de la cadena.

Si la tarea de la parte superior de la cadena es una tarea interna, la única forma de mitigar este problema sería finalizar la consulta y volver a ejecutarla más adelante.

A continuación, se muestra un resultado de ejemplo en el que la consulta de búsqueda está bloqueada en un bloqueo de la colección propiedad de otra tarea.

{ "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 }

Si "WaitState" tiene los valores "Latch", "SystemLock", "BufferLock", "BackgroundActivity" o "Other", la contención de recursos se debe a tareas internas del sistema. Si la situación continúa durante mucho tiempo, la única forma de mitigar este problema sería finalizar la consulta y volver a ejecutarla más adelante.

¿Cómo determino por qué de repente un sistema se ejecuta lentamente?

A continuación, se indican algunos motivos frecuentes de la ralentización del sistema:

  • Contención excesiva de recursos entre consultas simultáneas

  • El número de consultas simultáneas activas aumenta con el tiempo

  • Tareas internas del sistema como "GARBAGE_COLLECTION"

Para monitorizar el uso del sistema a lo largo del tiempo, ejecute la siguiente consulta "currentOp" periódicamente y envíe los resultados a un almacén externo. La consulta cuenta la cantidad de consultas y operaciones en cada espacio de nombres del sistema. A continuación, puede analizar los resultados de uso del sistema para conocer la carga del sistema y tomar las medidas adecuadas.

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

Esta consulta devuelve la suma de todas las consultas que se ejecutan en cada espacio de nombres, todas las tareas internas del sistema y el número único de estados de espera (si hay alguno) por espacio de nombres.

La salida de esta operación será similar a lo que se indica a continuación (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 }

En el resultado anterior, hay dos consultas de usuario en el espacio de nombres "db.test" que están bloqueadas en el bloqueo de colección: una consulta en el espacio de nombres "admin.$cmd" y una tarea interna "TTLMonitor".

Si el resultado indica muchas consultas con estados de espera de bloqueo, consulte ¿Cómo puedo encontrar y terminar las consultas que tardan mucho en ejecutarse o se bloquean?

¿Cómo determino la causa del uso elevado de la CPU en una o varias instancias de clúster?

Las secciones siguientes pueden ayudarle a identificar la causa del uso elevado de la CPU en una instancia. Los resultados pueden variar en función de la carga de trabajo.

En función del motivo del uso elevado de la CPU en la instancia, puede resultar útil realizar una o varias de las siguientes acciones.

  • Si la instancia principal presenta un uso elevado de la CPU, pero las instancias de réplica no, considere la posibilidad de distribuir el tráfico de lectura entre las réplicas a través de la configuración de preferencia de lectura del cliente (por ejemplo, secondaryPreferred). Para obtener más información, consulte Conexión a Amazon DocumentDB como conjunto de réplicas.

    Si se utilizan réplicas para las lecturas, se puede aprovechar mejor los recursos del clúster permitiendo que la instancia principal procese más tráfico de escritura. Las lecturas de las réplicas presentan consistencia final.

  • Si el uso elevado de la CPU se debe a la carga de trabajo de escritura, cambiar el tamaño de las instancias del clúster a un tipo de instancia mayor aumenta el número de núcleos de la CPU disponibles para atender la carga de trabajo. Para obtener más información, consulte instancias y Especificaciones de clases de instancias.

  • Si todas las instancias del clúster presentan un uso elevado de la CPU y la carga de trabajo utiliza réplicas para las lecturas, añadir más réplicas al clúster aumenta los recursos disponibles para el tráfico de lectura. Para obtener más información, consulte Agregación de una instancia de Amazon DocumentDB a un clúster.

¿Cómo determino los cursores abiertos en una instancia?

Cuando está conectado a una instancia Amazon DocumentDB, puede utilizar el comando db.runCommand("listCursors") para enumerar los cursores abiertos en esa instancia. Hay un límite de hasta 4560 cursores activos abiertos en un momento dado en una instancia determinada de Amazon DocumentDB, según el tipo de instancia. Por lo general, se recomienda cerrar cursores que ya no están en uso porque los cursores utilizan recursos en una instancia y tienen un límite superior. Consulte en Cuotas y límites de Amazon DocumentDB los límites específicos.

db.runCommand("listCursors")

¿Cómo determino la versión actual del motor de Amazon DocumentDB?

Para determinar la versión actual del motor de Amazon DocumentDB, ejecute el siguiente comando.

db.runCommand({getEngineVersion: 1})

La salida de esta operación será similar a lo que se indica a continuación (formato JSON).

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

La versión de motor de Amazon DocumentDB 3.6 es 1.x.x y la versión de motor de Amazon DocumentDB 4.0 es 2.x.x.

¿Cómo analizo el uso de los índices e identifico los índices no utilizados?

Para identificar los índices de una colección determinada, ejecute el siguiente comando:

db.collection.getIndexes()

Para analizar cuántos índices se utilizan durante las operaciones realizadas en las colecciones, se pueden utilizar los comandos collStats y indexStats. Para ver el número total de escaneos realizados con índices (escaneos de índices) en comparación con el número de escaneos realizados sin un índice (escaneos de colecciones), ejecute el siguiente comando:

db.collection.stats()

El resultado de este comando incluye los valores que se muestran a continuación:

  • idxScans: el número de escaneos realizados en esta colección mediante un índice.

  • collScans: el número de escaneos realizados en esta colección sin un índice. Estos escaneos habrían implicado revisar los documentos de la colección uno por uno.

  • lastReset: hora a la que se restablecieron estos contadores por última vez. Las estadísticas proporcionadas por este comando se restablecen al iniciar o detener el clúster o al escalar la instancia en dirección ascendente o descendente.

En el resultado del siguiente comando se muestra un desglose del uso de cada índice. Es una práctica recomendada identificar y eliminar regularmente los índices no utilizados para mejorar el rendimiento y reducir los costos, ya que de esta forma se eliminan las operaciones informáticas, de almacenamiento y de E/S innecesarias utilizadas para mantener los índices.

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

El resultado de este comando proporciona los siguientes valores para cada índice creado en la colección:

  • ops: el número de operaciones que utilizaron el índice. Si la carga de trabajo se ha ejecutado durante un tiempo suficientemente largo y está seguro de que se encuentra en un estado estable, un valor ops de cero indicaría que el índice no se utiliza en absoluto.

  • numDocsRead: el número de documentos leídos durante las operaciones que utilizan este índice.

  • since: el tiempo transcurrido desde que Amazon DocumentDB comenzó a recopilar estadísticas sobre el uso del índice, que suele ser el valor transcurrido desde la última acción de reinicio o mantenimiento de la base de datos.

  • size: tamaño de este archivo en bytes.

El siguiente ejemplo es una muestra del resultado de ejecutar el comando anterior:

{ "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" : ... } }

Para determinar el tamaño del índice general de una colección, ejecute el siguiente comando:

db.collection.stats()

Para eliminar un índice no utilizado, ejecute el siguiente comando:

db.collection.dropIndex("indexName")

¿Cómo identifico los índices que faltan?

Puede utilizar el generador de perfiles de Amazon DocumentDB para registrar consultas lentas. Una consulta que aparece repetidamente en el registro de consultas lentas puede indicar que se requiere un índice adicional para mejorar el rendimiento de esa consulta.

Puede identificar opciones de índices útiles buscando consultas de larga duración que tengan una o más etapas que realicen al menos una etapa COLLSCAN, lo que significa que la etapa de consulta tiene que leer todos los documentos de la colección para proporcionar una respuesta a la consulta.

En el ejemplo siguiente se muestra una consulta en una colección de viajes en taxi que se ejecutaron en una colección grande.

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

Para ejecutar este ejemplo, la consulta tuvo que realizar un análisis de la colección (es decir, leer cada documento de la colección), ya que no hay ningún índice en el campo fare.totalAmount. La salida del generador de perfiles de Amazon DocumentDB para esta consulta es similar a la siguiente:

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

Para acelerar la consulta de este ejemplo, crearía un índice en fare.totalAmount, como se muestra a continuación.

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

Los índices creados en el primer caso (es decir, cuando la opción {background:true} no se proporciona al crear el índice) utilizan un bloqueo de escritura exclusivo, lo que impide que las aplicaciones escriban datos en la colección hasta que se completa la creación del índice. Tenga en cuenta este impacto potencial al crear índices en clústeres de producción. Al crear índices, recomendamos configurar {background:true}.

En general, le convendrá crear índices en campos que tengan una cardinalidad alta (por ejemplo, un gran número de valores únicos). Crear un índice en un campo con cardinalidad baja puede producir un índice grande que no se utilice. El optimizador de consultas de Amazon DocumentDB tiene en cuenta el tamaño general de la colección y la selectividad de los índices al crear un plan de consulta. Hay momentos en los que verá que el procesador de consultas selecciona una etapa COLLSCAN incluso cuando un índice está presente. Esto sucede cuando el procesador de consultas estima que la utilización del índice no ofrecerá una ventaja de rendimiento sobre el análisis de toda la colección. Si desea obligar a que el procesador de consultas utilice un índice en particular, puede utilizar el operador hint() como se muestra a continuación.

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

Resumen de consultas útiles

Las siguientes consultas pueden resultar útiles para monitorizar el rendimiento y el uso de recursos en Amazon DocumentDB..

  • Utilice el siguiente comando para ver las estadísticas de una colección específica, incluidos los contadores de operaciones, las estadísticas de memoria caché, las estadísticas de acceso y las estadísticas de tamaño:

    db.collection.stats()
  • Utilice el siguiente comando para ver las estadísticas de cada índice creado en una colección, incluido el tamaño del índice, las estadísticas de caché específicas del índice y las estadísticas de uso del índice:

    db.collection.aggregate([{$indexStats:{}}]).pretty()
  • Utilice la siguiente consulta para ver toda la actividad.

    db.adminCommand({currentOp: 1, $all: 1});
  • El código siguiente muestra una lista de todas las consultas de ejecución prolongada o bloqueadas.

    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: {} });
  • El código siguiente finaliza una consulta.

    db.adminCommand({killOp: 1, op: <opid of running or blocked query>});
  • Utilice el código siguiente para obtener una vista acumulada del estado del sistema.

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