Limites de consulta

O Kusto é um motor de consulta ad hoc que aloja grandes conjuntos de dados e tenta satisfazer consultas ao manter todos os dados relevantes dentro da memória. Existe um risco inerente de as consultas monopolizarem os recursos de serviço sem limites. O Kusto fornece várias proteções incorporadas sob a forma de limites de consulta predefinidos. Se estiver a considerar remover estes limites, determine primeiro se realmente ganha algum valor ao fazê-lo.

Limite da simultaneidade do pedido

A simultaneidade dos pedidos é um limite que um cluster impõe a vários pedidos em execução ao mesmo tempo.

  • O valor predefinido do limite depende do SKU no qual o cluster está a ser executado e é calculado como: Cores-Per-Node x 10.
    • Por exemplo, para um cluster configurado no SKU D14v2, em que cada computador tem 16 vCores, o limite predefinido é 16 cores x10 = 160.
  • O valor predefinido pode ser alterado ao configurar a política de limite de taxa de pedidos do default grupo de cargas de trabalho.
    • O número real de pedidos que podem ser executados em simultâneo num cluster depende de vários fatores. Os fatores mais dominantes são o SKU do cluster, os recursos disponíveis do cluster e os padrões de utilização. A política pode ser configurada com base em testes de carga realizados em padrões de utilização semelhantes à produção.

Para obter mais informações, veja Optimize for high concurrency with Azure Data Explorer (Otimizar para elevada simultaneidade com o Azure Data Explorer).

Limitar o tamanho do conjunto de resultados (truncagem de resultados)

A truncagem de resultados é um limite definido por predefinição no conjunto de resultados devolvido pela consulta. O Kusto limita o número de registos devolvidos ao cliente para 500 000 e o tamanho global dos dados desses registos para 64 MB. Quando um destes limites é excedido, a consulta falha com uma "falha de consulta parcial". Exceder o tamanho geral dos dados irá gerar uma exceção com a mensagem:

The Kusto DataEngine has failed to execute a query: 'Query result set has exceeded the internal data size limit 67108864 (E_QUERY_RESULT_SET_TOO_LARGE).'

Exceder o número de registos falhará com uma exceção que diz:

The Kusto DataEngine has failed to execute a query: 'Query result set has exceeded the internal record count limit 500000 (E_QUERY_RESULT_SET_TOO_LARGE).'

Existem várias estratégias para lidar com este erro.

  • Reduza o tamanho do conjunto de resultados ao modificar a consulta para devolver apenas dados interessantes. Esta estratégia é útil quando a consulta com falhas inicial é demasiado "larga". Por exemplo, a consulta não projeta colunas de dados que não são necessárias.
  • Reduza o tamanho do conjunto de resultados ao transferir o processamento pós-consulta, como agregações, para a própria consulta. A estratégia é útil em cenários em que a saída da consulta é fornecida a outro sistema de processamento e, em seguida, faz outras agregações.
  • Mude de consultas para utilizar a exportação de dados quando quiser exportar grandes conjuntos de dados do serviço.
  • Instrua o serviço para suprimir este limite de consulta com set instruções listadas abaixo ou sinalizadores nas propriedades do pedido de cliente.

Os métodos para reduzir o tamanho do conjunto de resultados produzidos pela consulta incluem:

Pode desativar a truncagem de resultados com a opção notruncation de pedido. Recomendamos que ainda exista alguma forma de limitação.

Por exemplo:

set notruncation;
MyTable | take 1000000

Também é possível ter um controlo mais refinado sobre a truncagem de resultados ao definir o valor de (tamanho máximo de truncationmaxsize dados em bytes, predefinição para 64 MB) e truncationmaxrecords (número máximo de registos, predefinições para 500 000). Por exemplo, a consulta seguinte define a truncagem de resultados para ocorrer em 1105 registos ou 1 MB, o que for excedido.

set truncationmaxsize=1048576;
set truncationmaxrecords=1105;
MyTable | where User=="UserId1"

Remover o limite de truncagem de resultados significa que pretende mover dados em massa para fora do Kusto.

Pode remover o limite de truncagem de resultados para fins de exportação com o .export comando ou para agregação posterior. Se escolher a agregação posterior, considere agregar com o Kusto.

O Kusto fornece várias bibliotecas de cliente que podem processar resultados "infinitamente grandes" ao transmiti-los em fluxo para o autor da chamada. Utilize uma destas bibliotecas e configure-a para o modo de transmissão em fluxo. Por exemplo, utilize o cliente .NET Framework (Microsoft.Azure.Kusto.Data) e defina a propriedade de transmissão em fluxo do cadeia de ligação como verdadeira ou utilize a chamada ExecuteQueryV2Async() que transmite sempre os resultados. Para obter um exemplo de como utilizar ExecuteQueryV2Async(), veja a aplicação HelloKustoV2 .

Também pode considerar a aplicação de exemplo de ingestão de transmissão em fluxo C# útil.

A truncagem de resultados é aplicada por predefinição, não apenas ao fluxo de resultados devolvido ao cliente. Também é aplicada por predefinição a qualquer subconsulta que um cluster emita a outro cluster numa consulta entre clusters, com efeitos semelhantes.

Definir várias propriedades de truncagem de resultados

O seguinte aplica-se ao utilizar set instruções e/ou ao especificar sinalizadores nas propriedades do pedido de cliente.

  • Se notruncation estiver definido, e qualquer um dos truncationmaxsize, truncationmaxrecordsou query_take_max_records também estiverem definidos, notruncation será ignorado.
  • Se truncationmaxsize, truncationmaxrecords e/ou query_take_max_records forem definidos várias vezes, o valor mais baixo para cada propriedade é aplicado.

Limite da memória consumida pelos operadores de consulta (E_RUNAWAY_QUERY)

O Kusto limita a memória que cada operador de consulta pode consumir para proteger contra consultas "em execução". Este limite pode ser atingido por alguns operadores de consulta, como join e summarize, que operam ao armazenar dados significativos na memória. Por predefinição, o limite é de 5 GB (por nó de cluster) e pode ser aumentado ao definir a opção maxmemoryconsumptionperiteratorde pedido:

set maxmemoryconsumptionperiterator=68719476736;
MyTable | summarize count() by Use

Quando este limite é atingido, é emitida uma falha de consulta parcial com uma mensagem que inclui o texto E_RUNAWAY_QUERY.

The ClusterBy operator has exceeded the memory budget during evaluation. Results may be incorrect or incomplete E_RUNAWAY_QUERY.

The DemultiplexedResultSetCache operator has exceeded the memory budget during evaluation. Results may be incorrect or incomplete (E_RUNAWAY_QUERY).

The ExecuteAndCache operator has exceeded the memory budget during evaluation. Results may be incorrect or incomplete (E_RUNAWAY_QUERY).

The HashJoin operator has exceeded the memory budget during evaluation. Results may be incorrect or incomplete (E_RUNAWAY_QUERY).

The Sort operator has exceeded the memory budget during evaluation. Results may be incorrect or incomplete (E_RUNAWAY_QUERY).

The Summarize operator has exceeded the memory budget during evaluation. Results may be incorrect or incomplete (E_RUNAWAY_QUERY).

The TopNestedAggregator operator has exceeded the memory budget during evaluation. Results may be incorrect or incomplete (E_RUNAWAY_QUERY).

The TopNested operator has exceeded the memory budget during evaluation. Results may be incorrect or incomplete (E_RUNAWAY_QUERY).

Se maxmemoryconsumptionperiterator for definido várias vezes, por exemplo, nas propriedades do pedido de cliente e com uma set instrução, o valor inferior aplica-se.

Um limite adicional que pode acionar uma E_RUNAWAY_QUERY falha de consulta parcial é um limite do tamanho máximo acumulado das cadeias detidas por um único operador. Este limite não pode ser substituído pela opção de pedido acima:

Runaway query (E_RUNAWAY_QUERY). Aggregation over string column exceeded the memory budget of 8GB during evaluation.

Quando este limite é excedido, o mais provável é que o operador de consulta relevante seja , joinsummarizeou make-series. Para contornar o limite, deve modificar a consulta para utilizar a estratégia de consulta aleatória . (Também é provável que isto melhore o desempenho da consulta.)

Em todos os casos do , uma opção adicional (para além de E_RUNAWAY_QUERYaumentar o limite ao definir a opção de pedido e alterar a consulta para utilizar uma estratégia aleatória) é mudar para a amostragem. As duas consultas abaixo mostram como fazer a amostragem. A primeira consulta é uma amostragem estatística, utilizando um gerador de números aleatórios. A segunda consulta é a amostragem determinista, feita através do hash de algumas colunas do conjunto de dados, normalmente algum ID.

T | where rand() < 0.1 | ...

T | where hash(UserId, 10) == 1 | ...

Limite de memória por nó

A memória máxima por consulta por nó é outro limite utilizado para proteger contra consultas "em execução". Este limite, representado pela opção max_memory_consumption_per_query_per_nodede pedido, define um limite superior na quantidade de memória que pode ser utilizada num único nó para uma consulta específica.

set max_memory_consumption_per_query_per_node=68719476736;
MyTable | ...

Se max_memory_consumption_per_query_per_node for definido várias vezes, por exemplo, nas propriedades do pedido de cliente e com uma set instrução, o valor inferior aplica-se.

Se a consulta utilizar summarize, joinou make-series operadores, pode utilizar a estratégia de consulta aleatória para reduzir a pressão da memória num único computador.

Limite de tempo limite de execução

O tempo limite do servidor é um tempo limite do lado do serviço aplicado a todos os pedidos. O tempo limite para a execução de pedidos (consultas e comandos de gestão) é imposto em vários pontos do Kusto:

  • biblioteca de cliente (se utilizado)
  • ponto final de serviço que aceita o pedido
  • motor de serviço que processa o pedido

Por predefinição, o tempo limite está definido para quatro minutos para consultas e 10 minutos para comandos de gestão. Se necessário, este valor pode ser aumentado (limitado a uma hora).

  • Várias ferramentas de cliente suportam a alteração do tempo limite como parte das definições globais ou por ligação. Por exemplo, no Kusto.Explorer, utilize Opções de Ferramentas>*>Tempo Limite do Servidor de Consulta de Ligações>.
  • Programaticamente, os SDKs suportam a definição do tempo limite na servertimeout propriedade . Por exemplo, no SDK .NET, isto é feito através de uma propriedade de pedido de cliente, ao definir um valor do tipo .System.TimeSpan

Notas sobre tempos limite

  • Do lado do cliente, o tempo limite é aplicado a partir do pedido que está a ser criado até ao momento em que a resposta começa a chegar ao cliente. O tempo necessário para ler o payload no cliente não é tratado como parte do tempo limite. Depende da rapidez com que o autor da chamada obtém os dados da transmissão em fluxo.
  • Também no lado do cliente, o valor de tempo limite real utilizado é ligeiramente superior ao valor de tempo limite do servidor pedido pelo utilizador. Esta diferença é permitir latências de rede.
  • Para utilizar automaticamente o tempo limite máximo permitido do pedido, defina a propriedade norequesttimeout do pedido de cliente como true.

Nota

Veja Definir limites de tempo limite para um guia passo a passo sobre como definir tempos limite na IU da Web do Azure Data Explorer, Kusto.Explorer, Kusto.Cli, Power BI e ao utilizar um SDK.

Limitar a utilização de recursos da CPU de consulta

O Kusto permite-lhe executar consultas e utilizar tantos recursos de CPU como o cluster. Tenta fazer um round robin justo entre consultas se mais do que uma estiver em execução. Este método produz o melhor desempenho para funções definidas por consulta. Noutras alturas, poderá querer limitar os recursos da CPU utilizados para uma consulta específica. Se executar uma "tarefa em segundo plano", por exemplo, o sistema poderá tolerar latências mais elevadas para dar prioridade elevada às consultas inline simultâneas.

O Kusto suporta a especificação de duas propriedades de pedido ao executar uma consulta. As propriedades são query_fanout_threads_percent e query_fanout_nodes_percent. Ambas as propriedades são números inteiros predefinidos para o valor máximo (100), mas podem ser reduzidas para uma consulta específica para outro valor.

O primeiro, query_fanout_threads_percent, controla o fator de fanout para utilização de threads. Quando esta propriedade estiver definida como 100%, o cluster atribuirá todas as CPUs em cada nó. Por exemplo, 16 CPUs num cluster implementado nos nós do Azure D14. Quando esta propriedade estiver definida como 50%, será utilizada metade das CPUs e assim sucessivamente. Os números são arredondados para uma CPU inteira, pelo que é seguro definir o valor da propriedade como 0.

O segundo, query_fanout_nodes_percent, controla quantos dos nós de consulta no cluster utilizarão por operação de distribuição de subconsultas. Funciona de forma semelhante.

Se query_fanout_nodes_percent ou query_fanout_threads_percent forem definidos várias vezes, por exemplo, tanto nas propriedades do pedido de cliente como na utilização de uma set instrução, aplica-se o valor mais baixo para cada propriedade.

Limitar a complexidade das consultas

Durante a execução da consulta, o texto da consulta é transformado numa árvore de operadores relacionais que representam a consulta. Se a profundidade da árvore exceder um limiar interno, a consulta é considerada demasiado complexa para processamento e falhará com um código de erro. A falha indica que a árvore de operadores relacionais excede os limites.

Os exemplos seguintes mostram padrões de consulta comuns que podem fazer com que a consulta exceda este limite e falhe:

  • uma longa lista de operadores binários que estão acorrentados em conjunto. Por exemplo:
T 
| where Column == "value1" or 
        Column == "value2" or 
        .... or
        Column == "valueN"

Para este caso específico, reescreva a consulta com o in() operador.

T 
| where Column in ("value1", "value2".... "valueN")
  • uma consulta que tem um operador sindical que está a executar uma análise de esquema demasiado ampla, especialmente que o sabor predefinido da união é devolver o esquema de união "exterior" (ou seja, esse resultado incluirá todas as colunas da tabela subjacente).

A sugestão neste caso é rever a consulta e reduzir as colunas que estão a ser utilizadas pela consulta.