Limiti delle query

Kusto è un motore di query ad hoc che ospita set di dati di grandi dimensioni e tenta di soddisfare le query mantenendo tutti i dati pertinenti in memoria. Esiste un rischio intrinseco che le query monopolizzino le risorse del servizio senza limiti. Kusto offre diverse funzionalità di protezione predefinite, sotto forma di limiti di query predefiniti. Se si sta valutando la possibilità di rimuovere questi limiti, determinare innanzitutto se tale rimozione può portare effettivamente un vantaggio.

Limitare la concorrenza delle richieste

La concorrenza delle richieste è un limite imposto da un cluster a più richieste in esecuzione contemporaneamente.

  • Il valore predefinito del limite dipende dallo SKU su cui è in esecuzione il cluster e viene calcolato come : Cores-Per-Node x 10.
    • Ad esempio, per un cluster configurato nello SKU D14v2, in cui ogni computer ha 16 vCore, il limite predefinito è 16 cores x10 = 160.
  • Il valore predefinito può essere modificato configurando i criteri di limite di frequenza delle richieste del default gruppo di carico di lavoro.
    • Il numero effettivo di richieste che possono essere eseguite simultaneamente in un cluster dipende da vari fattori. I fattori più dominanti sono lo SKU del cluster, le risorse disponibili del cluster e i modelli di utilizzo. I criteri possono essere configurati in base ai test di carico eseguiti su modelli di utilizzo simili alla produzione.

Per altre informazioni, vedere Ottimizzare la concorrenza elevata con Azure Esplora dati.

Limite sulle dimensioni del set di risultati (troncamento dei risultati)

Il troncamento dei risultati è un limite impostato per impostazione predefinita sul set di risultati restituito dalla query. Kusto limita il numero di record restituiti al client a 500.000 e le dimensioni complessive dei dati per tali record a 64 MB. Se uno di questi limiti viene superato la query non riesce, restituendo un errore di query parziale. Il superamento delle dimensioni complessive dei dati genera un'eccezione con il messaggio seguente:

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).'

Il superamento del numero di record genera un'eccezione con il messaggio seguente:

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).'

Questo errore può essere gestito tramite diverse strategie.

  • Ridurre le dimensioni del set di risultati modificando la query in modo che restituisca solo i dati a cui si è interessati. Questa strategia è utile quando la query iniziale che ha generato un errore è troppo ampia. Ad esempio, la query non esclude le colonne di dati non necessarie.
  • Ridurre le dimensioni del set di risultati spostando l'elaborazione post-query, come le aggregazioni, nella query stessa. Questa strategia è utile negli scenari in cui l'output della query viene immesso in un altro sistema di elaborazione, che quindi esegue altre aggregazioni.
  • Passare dall'uso delle query all'uso dell'esportazione dati quando si vogliono esportare set di dati di grandi dimensioni dal servizio.
  • Indicare al servizio di rimuovere questo limite delle query usando le istruzioni set elencate di seguito o i flag nelle proprietà di richiesta client.

I metodi per ridurre le dimensioni del set di risultati prodotto dalla query includono:

È possibile disabilitare il troncamento dei risultati usando l'opzione di richiesta notruncation. È comunque consigliabile mantenere una qualche forma di limitazione.

Ad esempio:

set notruncation;
MyTable | take 1000000

È anche possibile ottenere un controllo più preciso sul troncamento dei risultati impostando il valore di truncationmaxsize (dimensioni massime dei dati in byte, il valore predefinito è 64 MB) e truncationmaxrecords (numero massimo di record, il valore predefinito è 500.000). Ad esempio, la query seguente imposta il troncamento dei risultati in corrispondenza di 1.105 record o 1 MB, a seconda del limite che viene superato per primo.

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

La rimozione del limite di troncamento dei risultati indica l'intenzione di spostare i dati in blocco all'esterno di Kusto.

È possibile rimuovere il limite di troncamento dei risultati ai fini dell'esportazione usando il comando .export o per eseguire un'aggregazione successivamente. Nel caso dell'aggregazione, è consigliabile eseguirla con Kusto.

Kusto fornisce alcune librerie client in grado di gestire risultati "infinitamente grandi" trasmettendoli al chiamante. Usare una di queste librerie e configurarla in modalità di trasmissione. Ad esempio, usare il client .NET Framework (Microsoft.Azure.Kusto.Data) e impostare la proprietà di trasmissione della stringa di connessione su true oppure usare la chiamata a ExecuteQueryV2Async() che trasmette sempre i risultati. Per un esempio di come usare ExecuteQueryV2Async(), vedere l'applicazione HelloKustoV2 .

È anche possibile trovare utile l'applicazione di esempio di inserimento in streaming C#.

Il troncamento dei risultati viene applicato per impostazione predefinita, non solo al flusso di risultati restituito al client. Viene applicato per impostazione predefinita anche a qualsiasi sottoquery che un cluster emette a un altro cluster in una query tra cluster, con effetti simili.

Impostazione di più proprietà di troncamento dei risultati

Quando si usano istruzioni set e/o si specificano flag nelle proprietà delle richieste client si verifica quanto segue.

  • Se la proprietà notruncation è impostata e anche truncationmaxsize, truncationmaxrecords o query_take_max_records è impostata, notruncation viene ignorata.
  • Se la proprietà truncationmaxsize, truncationmaxrecords e/o query_take_max_records viene impostata più volte, viene applicato il valore minore per ogni proprietà.

Limite per la memoria utilizzata dagli operatori di query (E_RUNAWAY_QUERY)

Kusto limita la memoria che ogni operatore di query può utilizzare per proteggersi dalle query "runaway". Questo limite può essere raggiunto da alcuni operatori di query, ad esempio join e summarize, che operano mantenendo dati significativi in memoria. Per impostazione predefinita, il limite è 5 GB (per nodo del cluster) e può essere aumentato impostando l'opzione maxmemoryconsumptionperiteratordi richiesta :

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

Quando viene raggiunto questo limite, viene generato un errore di query parziale con un messaggio che include il testo 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 l'opzione maxmemoryconsumptionperiterator viene impostata più volte, ad esempio in entrambe le proprietà della richiesta client, e si usa un'istruzione set, verrà applicato il valore minore.

Un limite aggiuntivo che potrebbe attivare un E_RUNAWAY_QUERY errore di query parziale è un limite per le dimensioni massime accumulate di stringhe mantenute da un singolo operatore. Questo limite non può essere sostituito dall'opzione di richiesta precedente:

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

Quando questo limite viene superato, probabilmente l'operatore di query pertinente è , joinsummarizeo make-series. Per aggirare il limite, è necessario modificare la query in modo da usare la strategia di query casuale . È anche probabile che ciò migliori le prestazioni della query.

In tutti i casi di E_RUNAWAY_QUERY, un'opzione aggiuntiva (oltre l'aumento del limite impostando l'opzione di richiesta e modificando la query in modo da usare una strategia casuale) consiste nel passare al campionamento. Le due query seguenti mostrano come eseguire il campionamento. La prima query è un campionamento statistico, usando un generatore di numeri casuali. La seconda query è il campionamento deterministico, eseguito eseguendo l'hashing di alcune colonne dal set di dati, in genere un ID.

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

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

Limite sulla memoria per nodo

La memoria massima per query per nodo è un altro limite usato come protezione dalle query con eccessivo tempo di esecuzione. Questo limite, rappresentato dall'opzione di richiesta max_memory_consumption_per_query_per_node, imposta un limite superiore sulla quantità di memoria che può essere usata in un singolo nodo per una query specifica.

set max_memory_consumption_per_query_per_node=68719476736;
MyTable | ...

Se l'opzione max_memory_consumption_per_query_per_node viene impostata più volte, ad esempio in entrambe le proprietà della richiesta client, e si usa un'istruzione set, verrà applicato il valore minore.

Se la query usa summarizeoperatori , joino make-series , è possibile usare la strategia di query casuale per ridurre la pressione della memoria in un singolo computer.

Limite al timeout esecuzione

Il timeout del server è un timeout sul lato servizio applicato a tutte le richieste. Il timeout sulle richieste in esecuzione (query e comandi di gestione) viene applicato in più punti in Kusto:

  • libreria client (se usata)
  • endpoint di servizio che accetta la richiesta
  • motore del servizio che elabora la richiesta

Per impostazione predefinita, il timeout è impostato su quattro minuti per le query e 10 minuti per i comandi di gestione. Questo valore può essere aumentato se necessario (fino al limite massimo di un'ora).

  • Vari strumenti client supportano la modifica del timeout come parte delle impostazioni globali o per ogni connessione. In Kusto.Explorer, ad esempio, usare Opzioni strumenti>* >Timeout del server di queryconnessioni>.
  • A livello di codice, gli SDK supportano l'impostazione del timeout tramite la servertimeout proprietà . Ad esempio, in .NET SDK questa operazione viene eseguita tramite una proprietà della richiesta client impostando un valore di tipo System.TimeSpan.

Note sui timeout

  • Sul lato client, il timeout viene applicato dalla richiesta creata fino al momento in cui la risposta inizia ad arrivare al client. Il tempo impiegato per leggere il payload nel client non viene considerato come parte del timeout. Dipende dalla rapidità con cui il chiamante estrae i dati dal flusso.
  • Sul lato client, inoltre, il valore di timeout effettivo usato è leggermente superiore rispetto al valore di timeout del server richiesto dall'utente. Questa differenza ha lo scopo di consentire le latenze di rete.
  • Per usare automaticamente il valore massimo consentito per il timeout delle richieste, impostare la proprietà della richiesta client norequesttimeout su true.

Nota

Vedere Impostare i limiti di timeout per una guida dettagliata su come impostare i timeout nell'interfaccia utente Web di Azure Esplora dati, Kusto.Explorer, Kusto.Cli, Power BI e quando si usa un SDK.

Limite sull'utilizzo delle risorse CPU delle query

Kusto consente di eseguire query e di usare tutte le risorse CPU di cui dispone il cluster. Se sono in esecuzione più query, cerca di eseguire un round robin equo tra di esse. Questo metodo restituisce le migliori prestazioni per le funzioni definite da query. In alcune situazioni può essere opportuno limitare le risorse CPU usate per una determinata query. Se si esegue un "processo in background", ad esempio, il sistema potrebbe tollerare latenze più elevate per assegnare priorità elevata alle query inline simultanee.

Kusto supporta la specifica di due proprietà di richiesta durante l'esecuzione di una query. Le proprietà sono query_fanout_threads_percent e query_fanout_nodes_percent. Entrambe le proprietà sono numeri interi che per impostazione predefinita corrispondono al valore massimo (100), ma questo valore può essere ridotto per una query specifica.

La prima proprietà, query_fanout_threads_percent, controlla il fattore di fan-out per l'uso dei thread. Se questa proprietà è impostata sul 100%, il cluster assegnerà tutte le CPU in ogni nodo. Ad esempio, 16 CPU in un cluster distribuito in nodi D14 di Azure. Se questa proprietà è impostata sul 50%, verrà usata la metà delle CPU e così via. I numeri vengono arrotondati per eccesso a un'intera CPU, quindi è possibile impostare il valore della proprietà su 0.

La seconda proprietà, query_fanout_nodes_percent, controlla il numero di nodi di query nel cluster da usare per ogni operazione di distribuzione delle sottoquery. Funziona in modo simile.

Se l'opzione query_fanout_nodes_percent o query_fanout_threads_percent viene impostata più volte, ad esempio in entrambe le proprietà della richiesta client, e si usa un'istruzione set, verrà applicato il valore minore.

Limite sulla complessità delle query

Durante l'esecuzione della query, il testo viene trasformato in un albero di operatori relazionali che rappresenta la query. Se la profondità dell'albero supera una soglia interna, la query viene considerata troppo complessa per l'elaborazione e avrà esito negativo con un codice di errore. L'errore indica che l'albero degli operatori relazionali supera i limiti.

Gli esempi seguenti illustrano modelli di query comuni che possono causare il superamento di questo limite e l'esito negativo della query:

  • lungo elenco di operatori binari concatenati. Ad esempio:
T 
| where Column == "value1" or 
        Column == "value2" or 
        .... or
        Column == "valueN"

Per questo caso specifico, riscrivere la query usando l'operatore in().

T 
| where Column in ("value1", "value2".... "valueN")
  • una query che dispone di un operatore union che esegue un'analisi dello schema troppo ampia, in particolare che il sapore predefinito dell'unione consiste nel restituire lo schema di unione "esterno", ovvero l'output includerà tutte le colonne della tabella sottostante.

Il suggerimento in questo caso consiste nel esaminare la query e ridurre le colonne usate dalla query.