Límites de la consulta

Kusto es un motor de consultas ad hoc que hospeda grandes conjuntos de datos e intenta satisfacer las consultas manteniendo todos los datos pertinentes en memoria. Existe un riesgo inherente de que las consultas monopolicen los recursos del servicio sin ningún límite. Kusto ofrece varias protecciones integradas en forma de límites de consulta predeterminados. Si está pensando en quitar estos límites, primero debe determinar si realmente resulta beneficioso hacerlo.

Límite de la simultaneidad de solicitudes

La simultaneidad de solicitudes es un límite que un clúster impone a varias solicitudes que se ejecutan al mismo tiempo.

  • El valor predeterminado de este límite depende del clúster de SKU en el que se ejecuta y se calcula de la siguiente manera: Cores-Per-Node x 10.
    • Por ejemplo, para un clúster configurado en la SKU D14v2, donde cada máquina tiene 16 núcleos virtuales, el límite predeterminado es 16 cores x10 = 160.
  • El valor predeterminado se puede cambiar mediante la configuración de la directiva de límite de frecuencia de solicitudes del grupo de cargas de trabajo default.
    • El número real de solicitudes que pueden ejecutarse simultáneamente en un clúster depende de varios factores. Los factores principales son la SKU del clúster, los recursos disponibles del clúster y los patrones de uso. La directiva se puede configurar en función de las pruebas de carga realizadas en patrones de uso similares a los de producción.

Para más información, consulte Optimización para alta simultaneidad con Azure Data Explorer.

Límite en el tamaño del conjunto de resultados (truncamiento del resultado)

El truncamiento del resultado es un límite establecido de manera predeterminada en el conjunto de resultados que devuelve la consulta. Kusto limita el número de registros que se devuelven al cliente a 500 000 y el tamaño total de los datos de esos registros a 64 MB. Cuando se supera alguno de estos límites, se produce un "error de consulta parcial" en la consulta. Si se supera el tamaño total de los datos, se generará una excepción con el siguiente mensaje:

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

Si se supera el número de registros, se producirá un error con una excepción que indicará lo siguiente:

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

Existen varias estrategias para solucionar este error.

  • Reduzca el tamaño del conjunto de resultados; para ello, modifique la consulta de modo que solo devuelva datos interesantes. Esta estrategia resulta útil cuando la consulta que inicialmente devolvió un error es demasiado "extensa". Por ejemplo, la consulta no excluye las columnas de datos que no son necesarias.
  • Reduzca el tamaño del conjunto de resultados; para ello, cambie el procesamiento posterior a la consulta, como las agregaciones, a la propia consulta. Esta estrategia resulta útil en escenarios en los que la salida de la consulta se pasa a otro sistema de procesamiento que, a continuación, realiza otras agregaciones.
  • Cambie de consultas a exportaciones de datos cuando quiera exportar conjuntos de datos de gran tamaño del servicio.
  • Indique al servicio que suprima este límite de consulta mediante las instrucciones set indicadas a continuación o las marcas en las propiedades de la solicitud de cliente.

Entre los métodos para reducir el tamaño del conjunto de resultados que genera la consulta se incluyen los siguientes:

Puede deshabilitar el truncamiento del resultado mediante la opción notruncation de la solicitud. Se recomienda que se siga implementando algún tipo de limitación.

Por ejemplo:

set notruncation;
MyTable | take 1000000

También es posible tener un control más preciso sobre el truncamiento del resultado si establece el valor de truncationmaxsize (tamaño máximo de datos en bytes, el valor predeterminado es 64 MB) y truncationmaxrecords (número máximo de registros, el valor predeterminado es 500 000). Por ejemplo, la siguiente consulta establece el truncamiento del resultado en 1105 registros o 1 MB, lo que se supere antes.

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

Si se quita el límite de truncamiento del resultado, se supone que pretende trasladar datos de manera masiva fuera de Kusto.

Puede quitar el límite de truncamiento del resultado con fines de exportación mediante el comando .export o para su posterior agregación. Si elige realizar la agregación posteriormente, considere la posibilidad realizarla mediante Kusto.

Kusto ofrece una serie de bibliotecas cliente que pueden administrar resultados "infinitamente grandes" al transmitirlos al autor de llamada. Use una de estas bibliotecas y configúrela en el modo streaming. Por ejemplo, use el cliente de .NET Framework (Microsoft.Azure.Kusto.Data) y establezca la propiedad streaming de la cadena de conexión en true, o bien use la llamada ExecuteQueryV2Async() que siempre transmite los resultados. Para obtener un ejemplo de cómo usar ExecuteQueryV2Async(), consulte la aplicación HelloKustoV2 .

También puede resultar útil la aplicación de ejemplo de ingesta de streaming de C#.

El truncamiento del resultado se aplica de manera predeterminada, no solo al flujo de resultados que se devuelve al cliente. También se aplica de manera predeterminada a cualquier subconsulta que un clúster emita a otro clúster en una consulta entre clústeres con efectos similares.

Establecimiento de varias propiedades de truncamiento de resultados

Se aplica lo siguiente cuando se usan instrucciones set y/o cuando se especifican marcas en las propiedades de la solicitud del cliente.

  • Si se establece notruncation y se establecen también truncationmaxsize, truncationmaxrecords o query_take_max_records, notruncation se omite.
  • Si se establecen truncationmaxsize, truncationmaxrecords o query_take_max_records varias veces, se aplicará el valor más bajo de cada propiedad.

Límite de memoria consumida por operadores de consulta (E_RUNAWAY_QUERY)

Kusto limita la memoria que cada operador de consulta puede consumir para protegerse frente a consultas "descontroladas". Algunos operadores de consulta pueden alcanzar este límite, como join y summarize, que funcionan manteniendo datos significativos en la memoria. De forma predeterminada, el límite es de 5 GB (por nodo de clúster) y se puede aumentar estableciendo la opción maxmemoryconsumptionperiteratorde solicitud :

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

Cuando se alcanza este límite, se emite un error de consulta parcial con un mensaje que incluye el 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).

Si maxmemoryconsumptionperiterator se establece varias veces, por ejemplo, en las propiedades de la solicitud de cliente y mediante una instrucción set, se aplicará el valor más bajo.

Un límite adicional que podría desencadenar un E_RUNAWAY_QUERY error de consulta parcial es un límite en el tamaño máximo acumulado de cadenas que mantiene un único operador. Esta opción de solicitud anterior no puede invalidar este límite:

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

Cuando se supera este límite, lo más probable es que el operador de consulta pertinente sea , joinsummarizeo make-series. Para solucionar el límite, se debe modificar la consulta para usar la estrategia de consulta aleatoria . (Esto también es probable que mejore el rendimiento de la consulta).

En todos los casos de , una opción adicional (más allá de E_RUNAWAY_QUERYaumentar el límite estableciendo la opción de solicitud y cambiando la consulta para usar una estrategia de orden aleatorio) es cambiar al muestreo. Las dos consultas siguientes muestran cómo realizar el muestreo. La primera consulta es un muestreo estadístico, que usa un generador de números aleatorios. La segunda consulta es un muestreo determinista, hecho mediante el hash de alguna columna del conjunto de datos, normalmente algún identificador.

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

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

Límite de memoria por nodo

La memoria máxima por consulta de nodo es otro límite que se usa para protegerse frente a consultas "descontroladas". Este límite, representado por la opción de solicitud max_memory_consumption_per_query_per_node, establece un límite superior para la cantidad de memoria que puede usarse en un solo nodo para una consulta específica.

set max_memory_consumption_per_query_per_node=68719476736;
MyTable | ...

Si max_memory_consumption_per_query_per_node se establece varias veces, por ejemplo, en las propiedades de la solicitud de cliente y mediante una instrucción set, se aplicará el valor más bajo.

Si la consulta utiliza los operadores summarize, joino make-series, puede usar la estrategia de consulta en orden aleatorio para reducir la presión en la memoria en una máquina individual.

Límite de tiempo de espera de ejecución

El tiempo de espera del servidor es un tiempo de espera del servicio que se aplica a todas las solicitudes. El tiempo de espera en las solicitudes en ejecución (consultas y comandos de administración) se aplica en varios puntos de Kusto:

  • la biblioteca cliente (si se usa)
  • el punto de conexión de servicio que acepta la solicitud
  • el motor de servicio que procesa la solicitud

De forma predeterminada, el tiempo de espera se establece en cuatro minutos para las consultas y 10 minutos para los comandos de administración. Este valor se puede aumentar si es necesario (limitado a una hora).

  • Varias herramientas de cliente admiten el cambio del tiempo de espera como parte de su configuración global o por conexión. Por ejemplo, en Kusto.Explorer, use Opciones de herramientas>* >Tiempo de espera del servidor de consultasde conexiones>.
  • Mediante programación, los SDK admiten la configuración del tiempo de espera a través de la servertimeout propiedad . Por ejemplo, en el SDK de .NET, esto se realiza a través de una propiedad de solicitud de cliente estableciendo un valor de tipo .System.TimeSpan

Notas sobre los tiempos de espera

  • En el lado cliente, se aplica el tiempo de espera de la solicitud que se está creando hasta el momento en que la respuesta comienza a llegar al cliente. El tiempo que se demora en leer la carga en el cliente no se cuenta como parte del tiempo de espera. Depende de la rapidez con la que el autor de la llamada extrae los datos de la secuencia.
  • También en el lado cliente, el valor de tiempo de espera real que se usa es ligeramente mayor que el valor de tiempo de espera del servidor que solicita el usuario. Esta diferencia busca tomar en cuenta las latencias de red.
  • Para usar automáticamente el tiempo de espera de solicitud máximo permitido, establezca la propiedad de solicitud de cliente norequesttimeout en true.

Nota

Consulte establecimiento de límites de tiempo de espera para obtener una guía paso a paso sobre cómo establecer tiempos de espera en la interfaz de usuario web de Azure Data Explorer, Kusto.Explorer, Kusto.Cli, Power BI y al usar un SDK.

Límite del uso de recursos de CPU de consulta

Kusto permite ejecutar consultas y usar tantos recursos de CPU como tenga el clúster. Intenta realizar una operación round robin equitativa entre las consultas si se está ejecutando más de una. Este método produce el mejor rendimiento para las funciones definidas por consultas. En otras ocasiones, quizá quiera limitar los recursos de CPU que se usan para una consulta determinada. Si ejecuta un "trabajo en segundo plano", por ejemplo, el sistema podría tolerar latencias más altas para dar prioridad alta a las consultas insertadas simultáneas.

Kusto admite la especificación de dos propiedades de solicitud al ejecutar una consulta. Las propiedades son query_fanout_threads_percent y query_fanout_nodes_percent. Ambas propiedades son números enteros que tienen como valor predeterminado el valor máximo (100), pero se pueden reducir para una consulta específica a algún otro valor.

La primera, query_fanout_threads_percent, controla el factor de distribución ramificada para el uso de subprocesos. Cuando esta propiedad esté establecida en 100 %, el clúster asignará todas las CPU de cada nodo. Por ejemplo, 16 CPU en un clúster implementado en nodos D14 de Azure. Cuando esta propiedad esté establecida en 50 %, se usará la mitad de las CPU, y así sucesivamente. Los números se redondean a una CPU completa, por lo que es posible establecer el valor de la propiedad en 0.

La segunda, query_fanout_nodes_percent, controla cuántos de los nodos de consulta del clúster se usarán en la operación de distribución de subconsultas. Funciona de manera similar.

Si query_fanout_nodes_percent o query_fanout_threads_percent se establecen varias veces, por ejemplo, en las propiedades de la solicitud de cliente y mediante una instrucción set, se aplicará el valor más bajo de cada propiedad.

Límite en la complejidad de consultas

Durante la ejecución de la consulta, el texto de la consulta se transforma en un árbol de operadores relacionales que representa a la consulta. Si la profundidad del árbol supera un umbral interno, la consulta se considera demasiado compleja para su procesamiento y se producirá un error con un código de error. El error indica que el árbol de operadores relacionales supera sus límites.

En los ejemplos siguientes se muestran patrones de consulta comunes que pueden hacer que la consulta supere este límite y genere un error:

  • una larga lista de operadores binarios encadenados. Por ejemplo:
T 
| where Column == "value1" or 
        Column == "value2" or 
        .... or
        Column == "valueN"

En este caso concreto, vuelva a escribir la consulta con el operador in().

T 
| where Column in ("value1", "value2".... "valueN")
  • una consulta que tiene un operador de unión que ejecuta un análisis de esquema demasiado amplio, especialmente que el tipo predeterminado de unión es devolver el esquema de unión "externo" (es decir, esa salida incluirá todas las columnas de la tabla subyacente).

La sugerencia en este caso es revisar la consulta y reducir las columnas que usa la consulta.