Desempenho e utilização de recursos - Amazon DocumentDB

As traduções são geradas por tradução automática. Em caso de conflito entre o conteúdo da tradução e da versão original em inglês, a versão em inglês prevalecerá.

Desempenho e utilização de recursos

Esta seção fornece perguntas e soluções para problemas comuns de diagnóstico em implantações do Amazon DocumentDB. Os exemplos fornecidos usam o shell do mongo e têm escopo definido como uma instância individual. Para encontrar um endpoint de instância, consulte Entendendo os endpoints do Amazon DocumentDB.

Como determino o número de operações de inserção, atualização e exclusão realizadas na minha coleção por meio da API do Mongo?

Para ver o número de operações de inserção, atualização e exclusão realizadas em uma determinada coleção, execute o seguinte comando nessa coleção:

db.collection.stats()

A saída deste comando descreve o seguinte no seu campo opCounters:

  • numDocsIns- O número de documentos inseridos nesta coleção. Isso inclui documentos inseridos usando os comandos insert e insertMany, bem como documentos inseridos por um upsert.

  • numDocsUpd- O número de atualizações de documentos nesta coleção. Isso inclui documentos atualizados usando os comandos update e findAndModify.

  • numDocsDel- O número de documentos excluídos dessa coleção. Isso inclui documentos excluídos usando os comandos deleteOne, deleteMany, remove e findAndModify.

  • lastReset: o horário em que esses contadores foram redefinidos pela última vez. As estatísticas fornecidas por esse comando são redefinidas ao iniciar/interromper o cluster ou ao aumentar/reduzir a instância.

Um exemplo de resultado da execução db.collection.stats() é mostrado abaixo.

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

Esse comando “stats” deve ser usado ao visualizar contadores específicos da coleção para operações de inserção, atualização e exclusão por meio da API do Mongo. Outra forma de visualizar os contadores de operações específicos da coleção é habilitar a auditoria de DML. O número de operações de inserção, atualização e exclusão em todas as coleções durante intervalos de um minuto pode ser visualizado em Monitorar o Amazon DocumentDB com métricas do CloudWatch.

Como faço para analisar o desempenho do cache?

A análise do desempenho do cache pode fornecer informações sobre a eficiência da recuperação de dados e o desempenho do sistema e é baseada na quantidade de dados lidos do disco em comparação aos do do cache. Fornecemos estatísticas de cache sobre o número de acessos (dados lidos do cache) e falhas de cache (dados que não são encontrados no cache e lidos do disco) para fornecer informações sobre o desempenho do cache. As estatísticas de cache de uma coleção específica podem ser encontradas executando o seguinte comando nessa coleção:

db.collection.stats()

Os valores no campo cacheStats de resultados desse comando fornecem estatísticas de cache para a coleção, bem como as estatísticas totais de cache para os índices criados na coleção. Essas estatísticas estão listadas abaixo:

  • collBlksHit: número de blocos lidos do cache durante as operações nessa coleção.

  • collBlksRead: número de blocos lidos do disco (falha de cache) durante as operações nessa coleção.

  • collHitRatio: taxa de acertos do cache para essa coleção (100 * [collBlksHit / (collBlksHit + collBlksRead)]).

  • idxBlksHit: número de blocos lidos do cache para qualquer índice criado nessa coleção.

  • idxBlksRead: número de blocos lidos do disco (falha de cache) para qualquer índice criado nessa coleção.

  • idxHitRatio: taxa de acerto do cache para os índices criados nessa coleção (100 * [idxBlksHit / (idxBlksHit + idxBlksRead)]).

  • lastReset: horário em que essas estatísticas foram redefinidas pela última vez. As estatísticas fornecidas por db.collection.stats() são redefinidas ao iniciar/interromper o cluster ou ao aumentar/diminuir a instância.

Um detalhamento dos campos idxBlksHit e idxBlksRead de cada índice também pode ser encontrado usando-se o comando indexStats. As estatísticas de cache específicas do índice podem ser encontradas executando-se o seguinte comando:

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

Para cada índice, as seguintes estatísticas de cache podem ser encontradas no campo cacheStats:

  • blksHit: número de blocos lidos do cache para esse índice.

  • blksRead: número de blocos lidos do disco para esse índice.

  • blksHitRatio: taxa de acertos do cache arredondada para quatro casas decimais, calculada por 100 * [blksHit / (blksHit + blksRead)].

Como faço para localizar e encerrar consultas bloqueadas ou de longa execução?

As consultas de usuário podem ser executadas lentamente devido a um plano de consulta pouco ideal ou podem ser bloqueadas devido à contenção de recursos.

Para encontrar consultas de longa execução que ficam lentas devido a um plano de consulta pouco ideal ou consultas bloqueadas devido à contenção de recursos, use o comando currentOp. Você pode filtrar o comando para ajudar a refinar a lista de consultas relevantes para serem encerradas. É necessário ter opid associado à consulta de longa duração para poder encerrar a consulta.

A consulta a seguir usa o comando currentOp para listar todas as consultas que estão bloqueadas ou em execução por mais 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: {} });

Depois, você pode restringir a consulta para encontrar o opid de uma consulta em execução por mais de 10 segundos e encerrá-lo.

Para localizar e encerrar uma consulta em execução por mais de 10 segundos
  1. Encontre o opid da consulta.

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

    A saída dessa operação é semelhante ao seguinte (formato JSON).

    { "waitedMS" : NumberLong(0), "cursor" : { "firstBatch" : [ { "opid" : 24646, "secs_running" : 12 } ], "id" : NumberLong(0), "ns" : "admin.$cmd" }, "ok" : 1 }
  2. Encerre a consulta usando a operação killOp.

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

Como posso ver um plano de consulta e otimizar uma consulta?

Se uma consulta for executada lentamente, pode ser porque a execução da consulta requer uma verificação completa da coleção para escolher os documentos relevantes. Às vezes, criar índices apropriados permitirá que a consulta seja executada mais rapidamente. Para detectar esse cenário e decidir os campos nos quais criar os índices, use o comando explain.

nota

O Amazon DocumentDB emula a API do MongoDB 3.6 em um mecanismo de banco de dados com propósito específico que utiliza um sistema de armazenamento distribuído, tolerante a falhas e de autorrecuperação. Como resultado, os planos de consulta e a saída de explain() podem diferir entre o Amazon DocumentDB e o MongoDB. Os clientes que desejam ter controle sobre seu plano de consulta podem usar o operador $hint para impor a seleção de um índice preferencial.

Execute a consulta que você deseja melhorar com o comando explain da seguinte forma.

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

Veja a seguir um exemplo de operação.

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

A saída dessa operação é semelhante ao seguinte (formato JSON).

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

A saída acima indica que o estágio $match exige a verificação de toda a coleção e a verificação se o campo "x" em cada documento é igual a 1. Se houver muitos documentos na coleção, a verificação da coleção (e, portanto, o desempenho geral da consulta) serão muito lentos. Assim, a presença de "COLLSCAN" na saída do comando explain indica que o desempenho da consulta pode ser aprimorado com a criação de índices apropriados.

Neste exemplo, a consulta verifica se o campo "x" é igual a 1 em todos os documentos. Portanto, criar um campo de índice no "x" permite que a consulta evite a verificação completa da coleção e use o índice para retornar os documentos relevantes mais cedo.

Depois de criar um índice no campo "x", a saída explain será a seguinte.

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

A criação de um índice no campo "x" permite que o estágio $match use uma varredura de índice para reduzir o número de documentos nos quais o predicado "x = 1" precisa ser avaliado.

Para pequenas coleções, o processador de consultas do Amazon DocumentDB pode optar por não usar um índice se os ganhos de desempenho forem negligenciáveis.

Como posso ver um plano de consulta em clusters elásticos?

Para examinar um plano de consulta em clusters elásticos, use o comando explain. Veja a seguir um exemplo de operação explain em uma consulta de busca direcionada a uma coleção fragmentada:

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

O Amazon DocumentDB emula o MongoDB em um mecanismo de banco de dados com propósito específico. Como resultado, os planos de consulta e a saída de explain() podem diferir entre o Amazon DocumentDB e o MongoDB. Você pode controlar seu plano de consulta com o uso do operador $hint para impor a seleção de um índice preferencial.

A saída dessa operação pode ser semelhante ao seguinte (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) }

A saída anterior mostra o plano de consulta para a consulta find em um cluster de três fragmentos. Cada fragmento tem várias partições de dados que podem ter diferentes estágios de entrada. Neste exemplo, um “COLLSCAN “(uma varredura de coleções) é executado em todas as partições antes que os resultados sejam mesclados no estágio “PARTITION_MERGE” dentro de cada fragmento. Os resultados dos fragmentos são, então, mesclados no estágio “SHARD_MERGE” antes de serem enviados de volta ao cliente.

Como faço para listar todas as operações em execução em uma instância?

Como usuário ou usuário principal, você geralmente quer listar todas as operações atuais em execução em uma instância para fins de diagnóstico e solução de problemas. (Para obter informações sobre o gerenciamento de usuários, consulte Gerenciando usuários do Amazon DocumentDB.)

Com o shell do mongo, você pode usar a seguinte consulta para listar todas as operações em execução em uma instância do Amazon DocumentDB.

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

A consulta retorna a lista completa de todas as consultas do usuário e tarefas internas do sistema atualmente em operação na instância.

A saída dessa operação é semelhante ao seguinte (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 }

Estes são valores válidos para o campo "desc":

  • INTERNAL — tarefas internas do sistema, como a limpeza do cursor ou tarefas de limpeza obsoletas do usuário.

  • TTLMonitor — thread de monitoramento Time to Live (TTL - vida útil). O status de execução é refletido no campo "active".

  • GARBAGE_COLLECTION — thread do coletor de lixo interno.

  • CONN — consulta do usuário.

  • CURSOR — a operação é um cursor inativo esperando que o usuário chame o comando "getMore" para obter o próximo lote de resultados. Nesse estado, o cursor está consumindo memória, mas não está consumindo nenhuma computação.

A saída anterior também lista todas as consultas do usuário em execução no sistema. Cada consulta de usuário é executada no contexto de um banco de dados e uma coleção, e a união desses dois é chamada de namespace. O namespace de cada consulta do usuário está disponível no campo "ns".

Às vezes, você precisa listar todas as consultas de usuário em execução em um determinado namespace. Portanto, a saída anterior deve ser filtrada no campo "ns". Um exemplo de consulta para alcançar a saída para filtrar é o seguinte. A consulta lista todas as consultas de usuário em execução no momento no banco de dados "db" e na coleção "test" (ou seja, o namespace "db.test").

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

Como usuário principal do sistema, você pode ver as consultas de todos os usuários e também todas as tarefas internas do sistema. Todos os outros usuários só podem ver suas respectivas consultas.

Se o número total de consultas e tarefas internas do sistema exceder o tamanho do lote padrão do cursor, o shell do mongo gerará automaticamente um objeto iterador 'it' para visualizar o resto dos resultados. Continue executando o comando 'it' até que todos os resultados sejam esgotados.

Como posso saber quando uma consulta está progredindo?

As consultas do usuário podem ficar lentas devido a um plano de execução de consulta pouco satisfatório ou ficar bloqueadas devido à contenção de recursos. Depurar essas consultas é um processo de várias etapas que pode exigir que a mesma etapa seja executada várias vezes.

A primeira etapa da depuração é listar todas as consultas que estão bloqueada ou de longa execução. A consulta a seguir lista todas as consultas de usuário que estão em execução por mais de 10 segundos ou que estão aguardando 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 a consulta anterior periodicamente para determinar se a lista de consultas muda e identificar as consultas bloqueadas ou de longa execução.

Se o documento de saída da consulta em questão tiver um campo WaitState, isso indica que a contenção de recursos é o motivo pelo qual a consulta está lenta ou bloqueada. A contenção de recursos pode ocorrer devido a E/S, tarefas internas do sistema ou outras consultas do usuário.

A saída dessa operação é semelhante ao seguinte (formato JSON).

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

E/S poderá ser um gargalo se houver muitas consultas em diferentes coleções em execução simultaneamente na mesma instância ou se o tamanho da instância for muito pequeno para o conjunto de dados no qual a consulta está sendo executada. Se as consultas forem somente leitura, você poderá atenuar a situação anterior separando as consultas de cada coleção em réplicas separadas. Para atualizações simultâneas em diferentes coleções ou quando o tamanho da instância for muito pequeno para o conjunto de dados, é possível mitigar aumentando a instância.

Se a contenção de recursos ocorrer devido a outra consulta do usuário, o campo "blockedOn" no documento de saída terá o "opid" da consulta que está afetando essa consulta. Com o "opid" siga a cadeia de campos "WaitState" e "blockedOn" de todas as consultas para encontrar a consulta à frente da cadeia.

Se a tarefa à frente da cadeia for uma tarefa interna, a única mitigação nesse caso seria encerrar a consulta e executá-la novamente depois de algum tempo.

Veja a seguir um exemplo de saída em que a consulta de busca é bloqueada em um bloqueio de coleção que pertence a outra tarefa.

{ "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" tiver valores "Latch", "SystemLock", "BufferLock", "BackgroundActivity" ou "Other", a origem da contenção de recursos serão as tarefas internas do sistema. Se a situação continuar por um longo período, a única atenuação será encerrar a consulta e executá-la novamente mais tarde.

Como determino por que um sistema fica lento repentinamente?

Veja a seguir alguns motivos comuns para uma desaceleração do sistema:

  • Contenção excessiva de recursos entre consultas simultâneas

  • O número de consultas simultâneas ativas aumentando ao longo do tempo

  • Tarefas internas do sistema, como "GARBAGE_COLLECTION"

Para monitorar o uso do sistema ao longo do tempo, execute a seguinte consulta "currentOp" periodicamente e gere a saída dos resultados em um armazenamento externo. A consulta conta o número de consultas e operações em cada namespace no sistema. É possível analisar os resultados do uso do sistema para compreender a carga no sistema e tomar a medida apropriada.

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

Essa consulta retorna um agregado de todas as consultas em execução em cada namespace e em todas as tarefas internas do sistema, e o número exclusivo de estados de espera, se houver, por namespace.

A saída dessa operação é semelhante ao seguinte (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 }

Na saída anterior, duas consultas de usuário no namespace "db.test" estão bloqueadas no bloqueio da coleção: uma consulta no namespace "admin.$cmd" e uma tarefa interna "TTLMonitor".

Se a saída indicar muitas consultas com estados de espera de bloqueio, consulte Como faço para localizar e encerrar consultas bloqueadas ou de longa execução?

Como determino a causa da alta utilização de CPU em uma ou mais instâncias de cluster?

As seções a seguir podem ajudá-lo a identificar a causa da alta utilização da CPU da instância. Os resultados podem variar dependendo da carga de trabalho.

Dependendo do motivo da alta utilização da CPU da instância, executar uma ou mais das ações a seguir pode ajudar.

  • Se a instância primária apresentar alta utilização de CPU, mas as instâncias de réplica não, considere distribuir o tráfego de leitura entre réplicas por meio de configurações de preferência de leitura do cliente (por exemplo, secondaryPreferred). Para ter mais informações, consulte Conectando-se ao Amazon DocumentDB como um conjunto de réplicas.

    O uso de réplicas para leituras pode fazer melhor uso dos recursos do cluster, permitindo que a instância primária processe mais tráfego de gravação. As leituras de réplicas do são eventualmente consistentes.

  • Se a alta utilização da CPU for resultado da carga de trabalho de gravação, alterar o tamanho das instâncias do cluster para um tipo de instância maior aumentará o número de núcleos de CPU disponíveis para atender à carga de trabalho. Para ter mais informações, consulte Instâncias e Especificações da classe de instância.

  • Se todas as instâncias de cluster exibirem alta utilização de CPU e a carga de trabalho estiver usando réplicas para leituras, adicionar mais réplicas ao cluster aumentará os recursos disponíveis para o tráfego de leitura. Para ter mais informações, consulte Adicionando uma instância do Amazon DocumentDB a um cluster.

Como posso determinar os cursores abertos em uma instância?

Quando estiver conectado a uma instância do Amazon DocumentDB, você poderá usar o comando db.runCommand("listCursors") para listar os cursores abertos nessa instância. Há um limite de até 4.560 cursores ativos abertos a qualquer momento em uma determinada instância do Amazon DocumentDB, dependendo do tipo de instância. Em geral, recomendamos fechar os cursores que não estão mais em uso, porque os cursores utilizam os recursos em uma instância e têm um limite superior. Consulte Cotas e limites do Amazon DocumentDB para obter os limites específicos.

db.runCommand("listCursors")

Como determinar a versão atual do mecanismo do Amazon DocumentDB?

Para determinar a versão atual do mecanismo do Amazon DocumentDB, execute o seguinte comando.

db.runCommand({getEngineVersion: 1})

A saída dessa operação é semelhante ao seguinte (formato JSON).

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

A versão do mecanismo do Amazon DocumentDB 3.6 é 1.x.x e a versão do mecanismo do Amazon DocumentDB 4.0 é 2.x.x.

Como analiso o uso do índice e identifico índices não utilizados?

Para identificar os índices de uma determinada coleção, execute o seguinte comando:

db.collection.getIndexes()

Para analisar quantos índices estão sendo usados durante as operações realizadas nas coleções, os comandos collStats e indexStats podem ser usados. Para visualizar o número total de varreduras realizadas usando índices (varreduras de índices) em comparação com o número de varreduras realizadas sem um índice (varreduras de coleções), execute o seguinte comando:

db.collection.stats()

O resultado desse comando inclui os seguintes valores:

  • idxScans: número de varreduras realizadas nessa coleção usando um índice.

  • collScans: número de varreduras realizadas nessa coleção sem usar um índice. Essas digitalizações envolveriam a análise dos documentos da coleção, um de cada vez.

  • lastReset: horário em que esses contadores foram redefinidos pela última vez. As estatísticas fornecidas por esse comando são redefinidas ao iniciar/interromper o cluster ou ao aumentar/reduzir a instância.

Um detalhamento de quanto cada índice é usado pode ser encontrado no resultado do comando a seguir. É uma prática recomendada identificar e remover regularmente índices não utilizados, a fim de melhorar o desempenho e reduzir custos, pois isso elimina computação, armazenamento e E/S desnecessários usados para manter os índices.

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

O resultado desse comando fornece os seguintes valores para cada índice criado na coleção:

  • ops - número de operações que usaram o índice. Se sua carga de trabalho estiver sendo executada por um tempo suficientemente longo e você estiver confiante de que ela está em um estado estável, um valor zero de ops indicaria que o índice não é usado.

  • numDocsRead: número de documentos lidos durante as operações usando esse índice.

  • since - tempo desde que o Amazon DocumentDB começou a coletar estatísticas sobre o uso do índice, que geralmente é o valor desde a última reinicialização ou ação de manutenção do banco de dados.

  • size - tamanho desse índice em bytes.

O exemplo a seguir é um exemplo de saída da execução do comando acima:

{ "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 o tamanho geral do índice para uma coleção, execute o seguinte comando:

db.collection.stats()

Para descartar um índice não utilizado, execute o seguinte comando:

db.collection.dropIndex("indexName")

Como identifico índices ausentes?

Você pode usar o profiler do Amazon DocumentDB para registrar consultas lentas em log. Uma consulta que aparece repetidamente no log de consulta lenta pode indicar que um índice adicional é necessário para melhorar o desempenho dessa consulta.

Você pode identificar oportunidades para índices úteis procurando consultas de longa execução que tenham um ou mais estágios que executem pelo menos um estágio COLLSCAN, o que significa que o estágio de consulta tem que ler todos os documentos na coleção para fornecer uma resposta à consulta.

O exemplo a seguir mostra uma consulta em uma coleção de corridas de táxi que foi executada em uma coleção grande.

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

Para executar este exemplo, a consulta tinha que realizar uma varredura na coleção (ou seja, ler todos os documentos da coleção), pois não há índice no campo fare.totalAmount. A saída do profiler do Amazon DocumentDB para essa consulta tem uma aparência semelhante à seguinte:

{ ... "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 a consulta neste exemplo, convém criar um índice no fare.totalAmount, como mostrado abaixo.

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

Os índices criados em primeiro plano (ou seja, se a opção {background:true} não foi fornecida ao criar o índice) usam um bloqueio de gravação exclusivo, o que impede que os aplicativos gravem dados na coleção até que a compilação do índice seja concluída. Esteja ciente desse possível impacto ao criar índices em clusters de produção. Ao criar índices, recomendamos a configuração {background:true}.

Em geral, convém criar índices em campos com cardinalidade alta (por exemplo, um grande número de valores exclusivos). Criar um índice em um campo com baixa cardinalidade pode resultar em um índice grande que não é usado. O otimizador de consulta do Amazon DocumentDB considera o tamanho geral da coleção e a seletividade dos índices ao criar um plano de consulta. Às vezes, você verá o processador de consultas selecionar um COLLSCAN mesmo quando um índice estiver presente. Isso acontece quando o processador de consultas estima que a utilização do índice não produzirá uma vantagem de desempenho sobre a varredura de toda a coleção. Se você quiser forçar o processador de consultas a utilizar um índice específico, use o operador hint() como mostrado abaixo.

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

Resumo de consultas úteis

As consultas a seguir podem ser úteis para monitorar o desempenho e a utilização de recursos no Amazon DocumentDB.

  • Use o comando a seguir para visualizar estatísticas sobre uma coleção específica, incluindo contadores de operação, estatísticas de cache, estatísticas de acessos e estatísticas de tamanho:

    db.collection.stats()
  • Use o comando a seguir para visualizar estatísticas sobre cada índice criado em uma coleção, incluindo o tamanho do índice, estatísticas de cache específicas do índice e estatísticas de uso do índice:

    db.collection.aggregate([{$indexStats:{}}]).pretty()
  • Use a consulta a seguir para listar todas as atividades.

    db.adminCommand({currentOp: 1, $all: 1});
  • O código a seguir lista todas as consultas bloqueadas ou de longa execução.

    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: {} });
  • O código a seguir encerra uma consulta.

    db.adminCommand({killOp: 1, op: <opid of running or blocked query>});
  • Use o código a seguir para obter uma visualização agregada do estado do sistema.

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