處理互動式工作流程中的大型查詢
互動式數據工作流程的挑戰是處理大型查詢。 這包括產生過多輸出行、提取大量外部分割,或對極大型數據集進行計算的查詢。 這些查詢可能會非常緩慢、飽和計算資源,並讓其他人難以共用相同的計算。
防止查詢獨占計算資源的查詢監控程序會檢查大型查詢的最常見原因,並終止超過閾值的查詢。 本文說明如何啟用和設定查詢監視程式。
重要
Query Watchdog 會針對所有使用者介面建立的通用計算啟用。
干擾式查詢的範例
分析師正在即時數據倉儲中執行一些臨時查詢。 分析師會使用共用自動調整計算,讓多個用戶輕鬆地同時使用單一計算。 假設有兩個數據表各有一百萬個數據列。
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
設定為較高的值。 同樣地,如果您想要在該查詢中的工作產生了一千萬行之後才停止查詢,您可以將 spark.databricks.queryWatchdog.minOutputRows
設定為一千萬。 任何較少的查詢都成功,即使超過輸出/輸入比率也一樣。
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 案例中使用的查詢,因為迴圈中通常沒有人為來更正錯誤。 建議您停用除臨機分析計算之外所有功能的查詢監視程式。