查詢限制

Kusto 是一種臨機操作查詢引擎,可裝載大型數據集,並嘗試藉由保存所有相關的記憶體中數據來滿足查詢。 但其固有風險是查詢會無上限地獨佔服務資源。 Kusto 會以預設查詢限制的形式提供數個內建保護。 如果您考慮移除這些限制,請先判斷您這麼做是否真的可獲得任何價值。

要求並行的限制

「要求並行」是叢集強加於數個同時執行的要求的限制。

  • 限制的預設值取決於叢集執行所在的 SKU,且計算方式為:Cores-Per-Node x 10
    • 例如,針對在 D14v2 SKU 上設定的叢集,其中每部機器都有 16 個虛擬核心,預設限制為 16 cores x10 = 160
  • 設定 default 工作負載群組的要求速率限制原則,即可變更預設值。
    • 可以在叢集上同時執行的實際要求數目取決於各種因素。 最主要的因素是叢集 SKU、叢集的可用資源和使用模式。 根據對類似生產使用模式執行的負載測試,來設定原則。

如需詳細資訊,請參閱使用 Azure 資料總管最佳化高並行

結果集大小的限制 (結果截斷)

結果截斷是預設的限制,會限制查詢所傳回的結果集。 Kusto 會將傳回給用戶端的記錄數目限制為 500,000,而這些記錄的整體資料大小會限制為 64 MB。 當其中一項限制超過時,查詢就會失敗並出現「部分查詢失敗」。 超過整體資料大小將會產生例外狀況,並出現下列訊息:

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 MB) 和 truncationmaxrecords (記錄數目上限,預設為 500,000),以更精確地控制結果截斷。 例如,下列查詢會將結果截斷設定為在超過 1,105 筆記錄或 1 MB 時發生。

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# 串流擷取範例應用程式很有用。

結果截斷會預設為套用狀態,而不只是套用至傳回給用戶端的結果串流。 根據預設,其也會套用至跨叢集查詢中一個叢集發給另一個叢集的所有子查詢,且效果類似。

設定多個結果截斷屬性

當使用 set 陳述式時,和/或在用戶端要求屬性中指定旗標時,適用下列情況。

  • 如果已設定 notruncation,而且也設定任何 truncationmaxsizetruncationmaxrecordsquery_take_max_records,則 notruncation 會遭忽略。
  • 如果 truncationmaxsizetruncationmaxrecords 和/或 query_take_max_records 會設定多次,則會套用每個屬性的「較低」值。

查詢運算子所耗用的記憶體限制 (E_RUNAWAY_QUERY)

Kusto 會限制每個查詢運算符可取用的記憶體,以防止「失控」查詢。 某些查詢運算符可能會達到此限制,例如 joinsummarize,這些運算符會藉由在記憶體中保存大量數據來運作。 根據預設,限制為每個叢集節點) 5GB (,而且可以藉由設定要求選項 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.

超過此限制時,最可能相關的查詢運算子是 joinsummarizemake-series。 若要解決限制,應該修改查詢以使用 隨機查詢 策略。 (這也可能會改善 query 的效能。)

在所有情況下 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 的語句中,則會套用較低的值。

如果查詢使用 summarizejoinmake-series 運算子,則您可以使用隨機查詢策略來降低單一機器的記憶體壓力。

執行逾時限制

伺服器逾時是套用至所有要求的服務端逾時功能。 (查詢和管理命令) 執行要求逾時,會在 Kusto 中的多個點強制執行:

  • 用戶端程式庫 (如果有使用的話)
  • 接受要求的服務端點
  • 處理要求的服務引擎

根據預設,查詢的逾時設定為四分鐘,而管理命令則設定為10分鐘。 如有需要,可以增加此值 (上限為一小時)。

  • 各種用戶端工具支援在其全域或個別連線設定中變更逾時。 例如,在 Kusto.Explorer 中,使用 [工具>選項] * > [連接>查詢伺服器逾時]。
  • 以程序設計方式,SDK 支援透過 servertimeout 屬性設定逾時。 例如,在 .NET SDK 中,這是透過 用戶端要求屬性來完成,方法是設定 類型的 System.TimeSpan值。

關於逾時的注意事項

  • 在用戶端上,套用逾時的範圍是從即將建立要求到回應開始到達用戶端的時間為止。 在用戶端上讀回承載所花費的時間,並不會被視為逾時的一部分。 這取決於呼叫端從串流中提取資料的速度。
  • 此外,在用戶端上使用的實際逾時值會稍微高於使用者要求的伺服器逾時值。 這種差異是將網路延遲納入考量。
  • 若要自動使用允許的要求逾時上限,請將用戶端要求屬性 norequesttimeout 設定為 true

注意

如需如何在 Azure Data Explorer Web UI、Kusto.Explorer、Kusto.Cli、Power BI 和使用 SDK 時設定逾時,請參閱設定逾時限制

查詢 CPU 資源使用量的限制

Kusto 可讓您執行查詢,並使用與叢集一樣多的 CPU 資源。 如果有一個以上的執行,其會嘗試在查詢之間進行公平的循環配置資源。 這個方法會產生查詢定義函式的最佳效能。 有時候,您可能會想要限制特定查詢所使用的 CPU 資源。 例如,如果您執行「背景工作」,系統可能會容許較高的延遲,以提供並行內嵌查詢高優先順序。

Kusto 支援在執行查詢時指定兩個 要求屬性 。 這些屬性為 query_fanout_threads_percent 和 query_fanout_nodes_percent。 這兩個屬性都是預設為最大值 (100) 的整數,但可能會針對特定查詢減少到某個其他值。

第一個屬性 query_fanout_threads_percent 會控制執行緒使用的扇出 (fanout) 因素。 當此屬性設為 100% 時,叢集將會在每個節點上指派所有 CPU。 例如,部署在 Azure D14 節點上的叢集上有 16 個 CPU。 當此屬性設為 50% 時,則會使用一半的 CPU,依此類推。 數字會無條件進位到一整個 CPU,因此可以放心地將屬性值設為 0。

第二個屬性 query_fanout_nodes_percent 會控制叢集中可供每個子查詢散發作業使用的查詢節點數。 其運作方式也類似。

如果 query_fanout_nodes_percentquery_fanout_threads_percent 設定多次,例如在用戶端要求屬性和使用 set 語句中,則會套用每個屬性較低的值。

查詢複雜度的限制

在查詢執行期間,查詢文字會轉換成代表查詢的關係運算子樹狀結構。 如果樹狀結構的深度超過內部閾值,則查詢會被視為太複雜而無法處理,而且將會失敗並產生錯誤碼。 此失敗表示關係運算子樹狀結構超過其限制。

下列範例顯示可能導致查詢超過此限制並失敗的一般查詢模式:

  • 鏈結在一起的二進位運算符長清單。 例如:
T 
| where Column == "value1" or 
        Column == "value2" or 
        .... or
        Column == "valueN"

在此特定案例中,請使用 in() 運算子來重寫查詢。

T 
| where Column in ("value1", "value2".... "valueN")
  • 聯集運算子執行太廣泛結構描述分析的查詢,特別是預設類別的聯集傳回「外部」聯集結構描述 (表示輸出將會包括基礎資料表的所有資料行)。

在此情況下,建議檢閱查詢,並減少查詢所使用的資料行。