分享方式:


處理互動式工作流程中的大型查詢

互動式數據工作流程的挑戰是處理大型查詢。 這包括產生太多輸出數據列、擷取許多外部數據分割,或計算極大型數據集的查詢。 這些查詢可能會非常緩慢、飽和計算資源,並讓其他人難以共用相同的計算。

查詢監看員是一個程式,可藉由檢查大型查詢和終止通過閾值的查詢,防止查詢壟斷計算資源。 本文說明如何啟用和設定查詢監視程式。

重要

查詢監看程式會針對使用UI建立的所有用途計算啟用。

干擾式查詢的範例

分析師正在 Just-In-Time 數據倉儲中執行一些臨機操作查詢。 分析師會使用共用自動調整計算,讓多個用戶輕鬆地同時使用單一計算。 假設有兩個數據表各有一百萬個數據列。

import org.apache.spark.sql.functions._
spark.conf.set("spark.sql.shuffle.partitions", 10)

spark.range(1000000)
  .withColumn("join_key", lit(" "))
  .createOrReplaceTempView("table_x")
spark.range(1000000)
  .withColumn("join_key", lit(" "))
  .createOrReplaceTempView("table_y")

這些數據表大小可在 Apache Spark 中管理。 不過,它們都會在每個數據列中包含具有 join_key 空字串的數據行。 如果數據不完全乾淨,或有顯著的數據扭曲,某些索引鍵比其他索引鍵更為普遍,就可能發生此情況。 這些空聯結索引鍵比任何其他值都更為普遍。

在下列程式代碼中,分析師在其索引鍵上聯結這兩個數據表,其會產生一萬億個結果輸出,所有這些結果都會在單一執行程式上產生(取得" "索引鍵的執行程式):

SELECT
  id, count(id)
FROM
  (SELECT
    x.id
  FROM
    table_x x
  JOIN
    table_y y
  on x.join_key = y.join_key)
GROUP BY id

此查詢似乎正在執行中。 但是,在不知道數據的情況下,分析師發現在執行作業的過程中,只剩下單一工作。 查詢永遠不會完成,讓分析人員感到沮喪,並混淆其運作原因。

在此情況下,只有一個有問題的聯結密鑰。 其他時候可能還有更多。

啟用和設定查詢監視程式

若要啟用及設定查詢監看程式,需要下列步驟。

  • 使用 spark.databricks.queryWatchdog.enabled啟用 Watchdog。
  • 使用 spark.databricks.queryWatchdog.minTimeSecs設定工作運行時間。
  • 使用 spark.databricks.queryWatchdog.minOutputRows顯示輸出。
  • 使用 spark.databricks.queryWatchdog.outputRatioThreshold設定輸出比率。

若要防止查詢為輸入資料列數目建立太多輸出數據列,您可以啟用查詢監視程式,並將輸出數據列數目上限設定為輸入數據列數目的倍數。 在此範例中,我們使用1000的比例(預設值)。

spark.conf.set("spark.databricks.queryWatchdog.enabled", true)
spark.conf.set("spark.databricks.queryWatchdog.outputRatioThreshold", 1000L)

後者組態會宣告任何指定的工作絕對不應該產生輸入數據列數目的 1000 倍以上。

提示

輸出比率是完全可自定義的。 建議您開始較低,並查看哪些閾值適用於您和您的小組。 1,000 到 10,000 的範圍是一個很好的起點。

查詢監看員不僅會防止使用者壟斷永遠不會完成之作業的計算資源,還能藉由快速失敗的查詢來節省時間。 例如,下列查詢會在幾分鐘后失敗,因為它超過比率。

SELECT
  z.id
  join_key,
  sum(z.id),
  count(z.id)
FROM
  (SELECT
    x.id,
    y.join_key
  FROM
    table_x x
  JOIN
    table_y y
  on x.join_key = y.join_key) z
GROUP BY join_key, z.id

以下是您會看到的內容:

查詢監視程式

通常足以啟用查詢監看狗並設定輸出/輸入閾值比例,但您也可以選擇設定兩個額外的屬性: spark.databricks.queryWatchdog.minTimeSecsspark.databricks.queryWatchdog.minOutputRows。 這些屬性會指定查詢中指定工作在取消之前必須執行的最小時間,以及該查詢中工作的輸出數據列數目下限。

例如,如果您想要讓每個工作產生大量數據列的機會,您可以設定 minTimeSecs 為較高的值。 同樣地,如果您想要只在該查詢中的工作產生 1000 萬個數據列之後停止查詢,您可以將 設定 spark.databricks.queryWatchdog.minOutputRows 為 1000 萬。 任何較少的查詢都成功,即使超過輸出/輸入比率也一樣。

spark.conf.set("spark.databricks.queryWatchdog.minTimeSecs", 10L)
spark.conf.set("spark.databricks.queryWatchdog.minOutputRows", 100000L)

提示

如果您在筆記本中設定查詢監看程式,則設定不會在計算重新啟動時保存。 如果您想要為計算的所有使用者設定 Query Watchdog,建議您使用 計算組態

偵測極大型數據集的查詢

另一個典型的大型查詢可能會從巨量數據表/數據集掃描大量數據。 掃描作業可能會持續很長一段時間並飽和計算資源(即使讀取大型Hive數據表的元數據可能需要相當長的時間)。 您可以將 設定 maxHivePartitions 為防止從大型 Hive 數據表擷取太多分割區。 同樣地,您也可以將 設定 maxQueryTasks 為限制極大型數據集的查詢。

spark.conf.set("spark.databricks.queryWatchdog.maxHivePartitions", 20000)
spark.conf.set("spark.databricks.queryWatchdog.maxQueryTasks", 20000)

何時應該啟用查詢監看程式?

查詢監看程式應該啟用臨機操作分析計算,其中 SQL 分析師和數據科學家正在共用指定的計算,而系統管理員必須確保查詢彼此「良好」地播放。

何時應該停用查詢監看程式?

一般而言,我們不建議急切地取消 ETL 案例中使用的查詢,因為迴圈中通常沒有人為來更正錯誤。 建議您針對除了臨機操作分析計算的所有功能停用查詢監視程式。