處理互動式工作流程中的大型查詢
互動式數據工作流程的挑戰是處理大型查詢。 這包括產生太多輸出數據列、擷取許多外部數據分割,或計算極大型數據集的查詢。 這些查詢可能會非常緩慢、飽和計算資源,並讓其他人難以共用相同的計算。
查詢監看員是一個程式,可藉由檢查大型查詢和終止通過閾值的查詢,防止查詢壟斷計算資源。 本文說明如何啟用和設定查詢監視程式。
重要
查詢監看程式會針對使用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.minTimeSecs
和 spark.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 案例中使用的查詢,因為迴圈中通常沒有人為來更正錯誤。 建議您針對除了臨機操作分析計算的所有功能停用查詢監視程式。