Поделиться через


Ограничения на запросы

Область применения: ✅Microsoft Fabric✅Azure Data ExplorerAzure MonitorMicrosoft Sentinel

Kusto — это нерегламентированный механизм запросов, в котором размещаются большие наборы данных и пытается удовлетворить запросы, удерживая все соответствующие данные в памяти. При обработке запросов существует риск того, что они монополизируют ресурсы служб, в которых не реализованы ограничения. Kusto предоставляет несколько встроенных возможностей защиты от таких рисков в виде ограничений запросов по умолчанию. Если вы хотите снять такие ограничения, сначала определите, даст ли вам это какие-либо фактические преимущества.

Ограничение на параллелизм запросов

Параллелизм запросов — это ограничение, которое применяется для нескольких запросов, выполняемых одновременно.

  • Значение ограничения по умолчанию зависит от номера SKU, в котором выполняется база данных, и вычисляется следующим образом: Cores-Per-Node x 10
    • Например, для базы данных, настроенной на SKU D14v2, где каждый компьютер имеет 16 виртуальных ядер, ограничение по умолчанию равно 16 cores x10 = 160.
  • Значение по умолчанию можно изменить, настроив политику ограничения частоты запросов для группы рабочей нагрузки default.
    • Фактическое количество запросов, которые могут выполняться одновременно в базе данных, зависит от различных факторов. Наиболее основными факторами являются SKU базы данных, доступные ресурсы базы данных и шаблоны использования. Политику можно настроить на основе результатов нагрузочных тестов, выполняемых для аналогичных шаблонов использования в рабочей среде.

Ограничение на размер результирующего набора (усечение результата)

Усечение результата — это ограничение, заданное по умолчанию для результирующего набора, возвращаемого запросом. Kusto ограничивает число записей, возвращаемых клиенту, до 500 000, а общий объем данных для таких записей — до 64 МБ. При превышении какого-либо из этих ограничений запрос завершается с частичным сбоем выполнения. Превышение общего объема данных приведет к возникновению исключения с таким сообщением:

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

Превышение числа записей приведет к сбою с таким исключением:

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

Есть несколько стратегий для устранения такой ошибки.

  • Уменьшите размер результирующего набора, изменив запрос, чтобы он возвращал только интересующие вас данные. Эта стратегия полезна, если изначальный запрос с ошибкой охватывает слишком широкий спектр данных, например не отбрасывает ненужные столбцы данных.
  • Уменьшите размер результирующего набора, реализовав в самом запросе последующую обработку, например агрегирование. Такая стратегия подходит для сценариев, в которых выходные данные запроса передаются в другую систему обработки для других операций агрегирования.
  • Чтобы экспортировать крупные наборы данных из службы, используйте функцию экспорта данных вместо запросов.
  • Используйте приведенные ниже инструкции set или флаги в свойствах клиентских запросов, чтобы указать службе не применять ограничение на запросы.

Вы можете использовать следующие методы для уменьшения размера результирующего набора, создаваемого запросом:

Вы можете отключить усечение результатов с помощью параметра запроса notruncation. Но мы все равно рекомендуем использовать ограничения в каком-либо виде.

Например:

set notruncation;
MyTable | take 1000000

Результат усечения также можно сделать еще более точным с помощью значений truncationmaxsize (максимальный размер данных в байтах, по умолчанию 64 МБ) и truncationmaxrecords (максимальное число записей, по умолчанию 500 000). Например, в приведенном ниже запросе усечение результатов выполняется при достижении 1105 записей или размера в 1 МБ (в зависимости от того, что произойдет раньше).

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

Отмена ограничения с усечением результатов приведет к тому, что из Kusto будут передаваться все данные.

Вы можете отменить это ограничение, если вы хотите экспортировать данные (с помощью команды .export) или выполнить дальнейшее агрегирование. Во втором случае мы рекомендуем для агрегирования использовать Kusto.

Kusto предоставляет несколько клиентских библиотек, которые могут обрабатывать "бесконечно большие" объемы результатов, передавая их вызывающему объекту в потоковом режиме. Используйте одну из таких библиотек и настройте ее для потоковой передачи. Например, используйте клиент .NET Framework (Microsoft.Azure.Kusto.Data) и задайте для свойства потоковой передачи в строке подключения значение true или используйте вызов ExecuteQueryV2Async(), который всегда выполняет потоковую передачу результатов. Пример использования ExecuteQueryV2Async()см. в приложении HelloKustoV2 .

Вы также можете ознакомиться с примером приложения для приема потоковой передачи с использованием C#.

Усечение результатов применяется по умолчанию, а не только к потоку результатов, возвращаемого клиенту.

Оно также применяется по умолчанию ко всем вложенным запросам, выдаваемым одним кластером другому кластеру в межкластерном запросе, и имеет аналогичное действие.

Он также применяется по умолчанию к любому подзапросу, что один eventhouse проблемы с другим хранилищем событий в запросе между событиями с аналогичными эффектами.

Установка нескольких свойств усечения результатов

При использовании инструкций set и (или) при указании флагов в свойствах клиентского запроса применяются следующие условия:

  • Если задано свойство notruncation и при этом установлен параметр truncationmaxsize, truncationmaxrecords или query_take_max_records, то notruncation игнорируется.
  • Если truncationmaxsize, truncationmaxrecords и (или) query_take_max_records заданы несколько раз, для каждого свойства применяется меньшее значение.

Ограничение объема памяти, потребляемой операторами запросов (E_RUNAWAY_QUERY)

Kusto ограничивает память, которую каждый оператор запроса может использовать для защиты от "беглых" запросов. Это ограничение может быть достигнуто некоторыми операторами запросов, такими как join и summarize, которые работают путем хранения значительных данных в памяти. По умолчанию ограничение составляет 5 ГБ (на узел), и его можно увеличить, задав параметр maxmemoryconsumptionperiteratorзапроса:

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

По достижении этого ограничения частичный сбой запроса создается с сообщением, включающим текст 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).

Если свойство maxmemoryconsumptionperiterator задано несколько раз, например в свойствах клиентского запроса и с помощью инструкции set, применяется меньшее значение.

Дополнительное ограничение, которое может вызвать частичный сбой E_RUNAWAY_QUERY запроса, является ограничением максимального размера строк, удерживаемых одним оператором. Это ограничение нельзя переопределить указанным выше параметром запроса:

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

Если это ограничение превышено, скорее всего, соответствующий оператор запроса имеет значение join, summarizeили make-series. Чтобы обойти ограничение, следует изменить запрос, чтобы использовать стратегию перетасовки запросов . (Это также может повысить производительность запроса.)

Во всех случаях E_RUNAWAY_QUERYдополнительный параметр (помимо увеличения ограничения путем задания параметра запроса и изменения запроса на использование стратегии перетасовки) заключается в переключении на выборку. На примере двух приведенных ниже запросов показано, как получить выборку. Первый запрос выполняет статистическую выборку, используя генератор случайных чисел. Второй запрос — детерминированная выборка, выполненная путем хэширования некоторых столбцов из набора данных, как правило, некоторых идентификаторов.

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

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

Ограничение на объем памяти для узла

Максимальный объем памяти на запрос для узла — это еще одно ограничение для защиты от неконтролируемых запросов. Это ограничение, представленное параметром запроса max_memory_consumption_per_query_per_node, задает верхнюю границу для объема памяти, который может использоваться отдельным узлом для конкретного запроса.

set max_memory_consumption_per_query_per_node=68719476736;
MyTable | ...

Если свойство max_memory_consumption_per_query_per_node задано несколько раз, например в свойствах клиентского запроса и с помощью инструкции set, применяется меньшее значение.

Если в запросе используются операторы summarize, join или make-series, вы можете использовать стратегию смешения запросов, чтобы уменьшить нагрузку на память на отдельном компьютере.

Ограничение на время ожидания выполнения

Время ожидания сервера — это время ожидания на стороне службы, применяемое ко всем запросам. Время ожидания при выполнении запросов (запросов и команд управления) применяется в нескольких точках в Kusto:

  • в клиентской библиотеке (если она используется);
  • на конечной точке службы, которая принимает запрос;
  • в подсистеме службы, которая обрабатывает запрос.

По умолчанию время ожидания составляет четыре минуты для запросов и 10 минут для команд управления. При необходимости его можно увеличить (до 1 часа).

  • Различные клиентские средства поддерживают изменение времени ожидания в рамках глобальных параметров или параметров подключения. Например, в Kusto.Explorer используйте параметры инструментов>* >Время ожидания сервера запросов к серверу запросов.>
  • Программным образом пакеты SDK поддерживают настройку времени ожидания через servertimeout свойство. Например, в пакете SDK для .NET это делается с помощью свойства запроса клиента, задав значение типа System.TimeSpan.

Примечания о времени ожидания

  • На стороне клиента временем ожидания считается время с момента создания запроса до момента получения ответа на клиенте. Время на считывание полезных данных на клиенте не учитывается во времени ожидания. Оно зависит от того, как быстро вызывающая сторона получает данные из потока.
  • Кроме того, на стороне клиента фактическое значение времени ожидания будет немного превышать значение времени ожидания сервера, запрашиваемое пользователем. Такая разница позволяет компенсировать задержку в сети.
  • Чтобы автоматически использовать максимально разрешенное время ожидания для запросов, задайте для свойства клиентского запроса norequesttimeout значение true.

Примечание.

Узнайте , как задать ограничения времени ожидания в пользовательском веб-интерфейсе Azure Data Explorer, Kusto.Explorer, Kusto.Cli, Power BI и использовании пакета SDK.

Ограничение на использование запросом ресурсов ЦП

Kusto позволяет выполнять запросы и использовать все доступные ресурсы ЦП, имеющиеся в базе данных. Kusto применяет циклический перебор со справедливым распределением ресурсов между запросами, если выполняется несколько запросов. Этот метод обеспечивает лучшую производительность для определяемых запросом функций. В других случаях вам может потребоваться ограничить объем ресурсов ЦП, используемый определенным запросом. Например, если вы запускаете фоновое задание, система может терпеть более высокие задержки, чтобы дать одновременные встроенные запросы с высоким приоритетом.

Kusto поддерживает указание двух свойств запроса при выполнении запроса. query_fanout_threads_percent и query_fanout_nodes_percent. Оба этих свойства являются целыми числами, которые по умолчанию принимают максимальное значение (100 %), но могут быть изменены на более низкое значение для определенного запроса.

Первое свойство, query_fanout_threads_percent, управляет коэффициентом разветвления для использования потоков. Если для этого свойства задано значение 100%, на каждом узле будут назначены все ЦП. Например, 16 ЦП, развернутых на узлах Azure D14. Если установить для этого свойства значение 50 %, будет использоваться половина ЦП, и т. д. Числа округляются до целых, поэтому для ЦП свойству можно присвоить значение 0.

Во-вторых, query_fanout_nodes_percent, определяет, сколько узлов запросов следует использовать для каждой операции распространения вложенного запроса. Она действует аналогичным образом.

Если свойство query_fanout_nodes_percent или query_fanout_threads_percent задано несколько раз, например в свойствах клиентского запроса и с помощью инструкции set, для каждого свойства применяется меньшее значение.

Ограничение на сложность запросов

Во время выполнения запроса его текст преобразуется в дерево операторов отношения, представляющих весь запрос. Если глубина дерева превышает внутренний порог, запрос считается слишком сложным для обработки и завершается ошибкой с кодом ошибки. Сбой указывает на то, что для дерева операторов отношения превышены ограничения.

В следующих примерах показаны распространенные шаблоны запросов, которые могут привести к превышению этого предела и сбою запроса

  • длинный список двоичных операторов, которые объединяются в цепочку. Например:
T
| where Column == "value1" or
        Column == "value2" or
        .... or
        Column == "valueN"

В таком случае мы рекомендуем переписать запрос с использованием оператора in().

T
| where Column in ("value1", "value2".... "valueN")
  • Запрос, имеющий оператор объединения, выполняющий слишком широкий анализ схемы, особенно что стандартный вариант объединения — возвращать "внешнюю" схему объединения (то есть выходные данные будут включать все столбцы базовой таблицы).

В этом случае рекомендуется просмотреть запрос и уменьшить количество столбцов, используемых запросом.