メインコンテンツまでスキップ

I/Oが少ない低速のSparkステージ

I/O があまりない遅いステージの場合、これは次の原因で発生する可能性があります。

  • たくさんの小さなファイルを読む
  • 小さなファイルをたくさん書き込む
  • 低速 UDF(秒)
  • デカルト結合
  • 結合の爆発

これらの問題のほとんどすべては、SQL DAG を使用して特定できます。

SQL DAG を開く

SQL DAG を開くには、ジョブのページの上部までスクロールし、[ Associated SQL Query ] をクリックします。

SQL ID

DAG が表示されます。 そうでない場合は、少しスクロールすると表示されます。

SLQのDAG

先に進む前に、DAGと時間が費やされている場所をよく理解してください。 DAG の一部のノードには、役立つ時間情報があり、他のノードにはないノードがあります。 たとえば、次のブロックは 2.1 分かかり、ステージ ID も提供します。

Slow Stage ノード

このノードを開くと、1.4 分かかったことがわかります。

低速書き込みノード

これらの時間は累積的であるため、クロック時間ではなく、すべてのタスクに費やされた合計時間です。 しかし、それらはクロック時間とコストと相関しているため、それでも非常に便利です。

DAGのどこに時間が費やされているかをよく理解しておくと便利です。

たくさんの小さなファイルを読む

スキャンオペレーターの1つに時間がかかる場合は、それを開いて読み取られたファイルの数を探します。

多数のファイルの読み込み

数万以上のファイルを読み取っている場合は、小さなファイルに問題がある可能性があります。 ファイルは8MB以上である必要があります。 小さいファイルの問題は、ほとんどの場合、列が多すぎるか、カーディナリティの高い列でパーティション分割されていることが原因です。

運が良ければ、 OPTIMIZEを実行するだけで済むかもしれません。 いずれにせよ、 ファイルのレイアウトを再考する必要があります。

小さなファイルをたくさん書き込む

書き込みに時間がかかる場合は、ファイルの数と書き込まれたデータの量を探して、それを開いてください。

多数のファイルを書き込む

数万以上のファイルを書き込んでいる場合は、小さなファイルの問題が発生している可能性があります。 ファイルは8MB以上である必要があります。 小さいファイルの問題は、ほとんどの場合、列が多すぎるか、カーディナリティの高い列でパーティション分割されていることが原因です。 ファイルのレイアウトを再考するか、最適化された書き込みを有効にする必要があります。

低速 UDF

UDFがあることがわかっている場合、またはDAGに次のようなものが表示される場合は、UDFが遅いことに苦しんでいる可能性があります。

UDF ノード

この問題に苦しんでいると思われる場合は、UDF をコメントアウトして、パイプラインの速度にどのように影響するかを確認してください。 UDF が実際に時間が費やされている場所にある場合、最善の策はネイティブ関数を使用して UDF を書き換えることです。 それが不可能な場合は、UDF を実行するステージ内のタスクの数を考慮してください。 クラスターのコア数よりも少ない場合は、 UDFを使用する前にデータフレームをrepartition()してください。

Python
  (df
.repartition(num_cores)
.withColumn('new_col', udf(...))
)

UDFs は、メモリの問題に悩まされることもあります。 各タスクは、そのパーティション内のすべてのデータをメモリにロードする必要がある場合があることを考慮してください。 このデータが大きすぎると、処理が非常に遅くなったり、不安定になったりする可能性があります。 再パーティション化は、各タスクを小さくすることでこの問題を解決することもできます。

デカルト結合

DAG にデカルト結合またはネスト ループ結合が表示されている場合は、これらの結合が非常に高価であることを知っておく必要があります。 それが意図したものであることを確認し、別の方法があるかどうかを確認します。

爆発結合または分解

ノードに数行が入り、さらに多くの行が出てくる場合は、爆発的な結合またはexplode()に苦しんでいる可能性があります。

エクスプロード ジョイン

爆発の詳細については、 Databricks 最適化ガイドをご覧ください。