次の方法で共有


対話型ワークフローでの大規模なクエリの処理

対話型データ ワークフローの課題は、大規模なクエリを処理することです。 これには、出力行の生成が多すぎるクエリ、多数の外部パーティションをフェッチするクエリ、または非常に大きなデータ セットに対する計算が含まれます。 これらのクエリは非常に低速で、コンピューティング リソースが飽和し、他のユーザーが同じコンピューティングを共有することが困難になる可能性があります。

Query Watchdog は、大規模なクエリの最も一般的な原因を調べ、しきい値を超えるクエリを終了することで、クエリがコンピューティング リソースを独占できないようにするプロセスです。 この記事では、Query Watchdog を有効にして構成する方法について説明します。

Von Bedeutung

クエリ ウォッチドッグは、UI を使用して作成されたすべての汎用コンピューティングに対して有効になります。

破壊的クエリの例

アナリストは、Just-In-Time データ ウェアハウスで一部のアドホック クエリを実行しています。 アナリストは、共有自動スケーリング コンピューティングを使用するため、複数のユーザーが 1 つのコンピューティングを同時に簡単に使用できます。 それぞれ 100 万行のテーブルが 2 つあるとします。

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 列が含まれています。 これは、データが完全にクリーンでない場合や、一部のキーが他のキーよりも一般的な大きなデータ スキューがある場合に発生する可能性があります。 これらの空の結合キーは、他のどの値よりもはるかに一般的です。

次のコードでは、アナリストはキーに対してこれら 2 つのテーブルを結合しています。これにより 1 兆の結果の出力が生成され、これらすべてが 1 つの Executor ( " " キーを取得する Executor) で生成されます。

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

このクエリは実行中のようです。 しかし、アナリストはデータについて知らずに、ジョブの実行過程でわずか1つのタスクしか残っていないことを確認します。 クエリは完了せず、アナリストはなぜ機能しなかったのか不満と混乱を残します。

この場合、問題のある結合キーは 1 つだけです。 その他の場合は、さらに多くの場合があります。

クエリ ウォッチドッグを有効にして構成する

Query Watchdog を有効にして構成するには、次の手順が必要です。

  • spark.databricks.queryWatchdog.enabledでウォッチドッグを有効にします。
  • spark.databricks.queryWatchdog.minTimeSecsを使用してタスク ランタイムを構成します。
  • spark.databricks.queryWatchdog.minOutputRowsで出力を表示します。
  • spark.databricks.queryWatchdog.outputRatioThresholdを使用して出力比率を構成します。

クエリが入力行数に対して多すぎる出力行を作成できないようにするには、Query Watchdog を有効にし、出力行の最大数を入力行数の倍数として構成します。 この例では、比率 1000 (既定値) を使用します。

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

後者の構成では、特定のタスクが入力行数の 1,000 倍を超える値を生成しないように宣言しています。

ヒント

出力比は完全にカスタマイズ可能です。 低い値から始めて、自分とチームに適したしきい値を確認することをお勧めします。 1,000 ~ 10,000 の範囲が適切な開始点です。

Query Watchdog は、完了しないジョブのコンピューティング リソースをユーザーが独占するのを防ぐだけでなく、完了しなかったクエリを高速に失敗させることで時間を節約します。 たとえば、次のクエリは比率を超えるため、数分後に失敗します。

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の 2 つの追加プロパティを設定することもできます。 これらのプロパティは、クエリ内の特定のタスクを取り消す前に実行する必要がある最小時間と、そのクエリ内のタスクの出力行の最小数を指定します。

たとえば、タスクごとに多数の行を生成する機会を与える場合は、 minTimeSecs を高い値に設定できます。 同様に、クエリ内のタスクが 1,000 万行を生成した後でのみクエリを停止する場合は、 spark.databricks.queryWatchdog.minOutputRows を 1,000 万に設定できます。 出力/入力の比率を超えた場合でも、それ以下の値を指定するとクエリは成功します。

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

ヒント

ノートブックで Query Watchdog を構成した場合、コンピューティングの再起動後も構成は保持されません。 コンピューティングのすべてのユーザーに対して Query Watchdog を構成する場合は、 コンピューティング構成を使用することをお勧めします。

非常に大きなデータセットに対するクエリを検出する

もう 1 つの一般的な大規模なクエリでは、ビッグ テーブル/データセットから大量のデータをスキャンできます。 スキャン操作が長時間続き、コンピューティング リソースが飽和する可能性があります (大きな Hive テーブルのメタデータの読み取りにもかなりの時間がかかる場合があります)。 maxHivePartitionsを設定して、大きな Hive テーブルからフェッチするパーティションが多くなりすぎないようにすることができます。 同様に、 maxQueryTasks を設定して、非常に大規模なデータセットに対するクエリを制限することもできます。

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

クエリ ウォッチドッグを有効にする必要があるタイミング

クエリ ウォッチドッグは、SQL アナリストとデータ サイエンティストが特定のコンピューティングを共有しているアドホック分析コンピューティングに対して有効にする必要があります。管理者は、クエリが互いに "正常に再生" されるようにする必要があります。

クエリ ウォッチドッグを無効にする必要があるタイミング

一般に、ETL シナリオで使用されるクエリを熱心に取り消すことをお勧めしません。通常、エラーを修正するための人間がいないためです。 アドホック分析コンピューティング以外のすべてに対してクエリ ウォッチドッグを無効にすることをお勧めします。