Bloqueie queries lentas com filtros de Rejeição de Operação
Novidades na versão 8.0.
Para evitar que uma operação cause volume de trabalho excessivo, você pode rejeitar temporariamente todas as operações associadas a essaforma de query . Para fazer isso, use setQuerySettings
para definir o campo reject
como true
para a forma de query da operação. Uma forma de query rejeitada também é conhecida como filtro de aceitação de operação.
O otimizador de query usa as configurações de query como uma entrada adicional durante o planejamento de query, o que afeta o plano selecionado para executar a query.
As etapas nesta página criam uma collection de exemplo e usam um filtro de aceitação de operação para bloquear uma forma de query.
Sobre esta tarefa
Suponha que um cluster tenha volume de trabalho excessivo porque um aplicação tem uma query ineficiente. Para evitar que a query consuma recursos excessivos do cluster, use um filtro de aceitação de operação para bloquear a execução da query e de queries semelhantes.
Antes de começar
Para identificar uma query ineficiente, use vários métodos que incluem:
Passos
Criar a coleção de exemplo
Executar:
// Create pizzaOrders collection db.pizzaOrders.insertMany( [ { _id: 0, type: "pepperoni", size: "small", price: 19, totalNumber: 10, orderDate: ISODate( "2023-03-13T08:14:30Z" ) }, { _id: 1, type: "pepperoni", size: "medium", price: 20, totalNumber: 20, orderDate: ISODate( "2023-03-13T09:13:24Z" ) }, { _id: 2, type: "pepperoni", size: "large", price: 21, totalNumber: 30, orderDate: ISODate( "2023-03-17T09:22:12Z" ) }, { _id: 3, type: "cheese", size: "small", price: 12, totalNumber: 15, orderDate: ISODate( "2023-03-13T11:21:39.736Z" ) }, { _id: 4, type: "cheese", size: "medium", price: 13, totalNumber: 50, orderDate: ISODate( "2024-01-12T21:23:13.331Z" ) }, { _id: 5, type: "cheese", size: "large", price: 14, totalNumber: 10, orderDate: ISODate( "2024-01-12T05:08:13Z" ) }, { _id: 6, type: "vegan", size: "small", price: 17, totalNumber: 10, orderDate: ISODate( "2023-01-13T05:08:13Z" ) }, { _id: 7, type: "vegan", size: "medium", price: 18, totalNumber: 10, orderDate: ISODate( "2023-01-13T05:10:13Z" ) } ] )
Adicionar um filtro de descarte de operação
Execute o seguinte comando setQuerySettings
para adicionar um filtro de aceitação de operação com estes campos:
find
com um filtro e uma classificação, que define a forma de query.$db
com o banco de dados de dados para as configurações de consulta.settings
que rejeitam a forma de query.
db.adminCommand( { setQuerySettings: { find: "pizzaOrders", filter: { orderDate: { $gt: ISODate( "2023-01-20T00:00:00Z" ) } }, sort: { totalNumber: 1 }, $db: "test" }, settings: { reject: true } } )
A seguinte saída truncada mostra o valor de campo queryShapeHash
e o campo settings reject
é true
:
{ queryShapeHash: 'AB8ECADEE8F0EB0F447A30744EB4813AE7E0BFEF523B0870CA10FCBC87F5D8F1', settings: { reject: true }, representativeQuery: { find: 'pizzaOrders', filter: { orderDate: { '$gt': ISODate('2023-01-20T00:00:00.000Z') } }, sort: { totalNumber: 1 }, '$db': 'test' }, ok: 1, ... }
(Opcional) Use o comando de explicação para confirmar as configurações
Execute explain
:
db.pizzaOrders.explain().find( { orderDate: { $gt: ISODate( "2023-01-20T00:00:00Z" ) } } ).sort( { totalNumber: 1 } )
A seguinte saída truncada mostra que o campo querySettings reject
é true
:
{ queryPlanner: { winningPlan: { stage: 'SINGLE_SHARD', shards: [ { explainVersion: '1', ... namespace: 'test.pizzaOrders', parsedQuery: { orderDate: { '$gt': ISODate('2023-01-20T00:00:00.000Z') } }, querySettings: { reject: true }, ... } ] } }
(Opcional) Remova o filtro de aceitação da operação
O exemplo a seguir usa removeQuerySettings
para remover o filtro de aceitação da operação, que é identificado usando o valor queryShapeHash
da saída mostrada na etapa 2 anterior:
db.adminCommand( { removeQuerySettings: "AB8ECADEE8F0EB0F447A30744EB4813AE7E0BFEF523B0870CA10FCBC87F5D8F1" } )
Você também pode obter o valor de queryShapeHash
de:
Você também pode remover um filtro de descarte de operação usando uma forma de query. Por exemplo:
db.adminCommand( { removeQuerySettings: { find: "pizzaOrders", filter: { orderDate: { $gt: ISODate( "2023-01-20T00:00:00Z" ) } }, sort: { totalNumber: 1 }, $db: "test" } } )
Próximos passos
Depois de bloquear uma operação ineficiente usando um filtro de aceitação de operação, o desempenho do cluster deve retornar ao que era antes da introdução da query ineficiente. Próximas etapas:
Resolva o problema de desempenho com a query. Isso pode exigir um índice ou uma reescrita de query.
Implemente o aplicação atualizado.
Para reativar as configurações de query que não foram excluídas, use setQuerySettings
e defina o campo reject
como false
.