web-dev-qa-db-ja.com

Spark Pythonを使用:ステージxの解決方法には、非常に大きなサイズ(xxx KB)のタスクが含まれます。最大推奨タスクサイズは100 KBです。

作成したばかりのpython range(1,100000)のリスト。

SparkContextを使用して、次の手順を実行しました。

a = sc.parallelize([i for i in range(1, 100000)])
b = sc.parallelize([i for i in range(1, 100000)])

c = a.Zip(b)

>>> [(1, 1), (2, 2), -----]

sum  = sc.accumulator(0)

c.foreach(lambda (x, y): life.add((y-x)))

次のような警告が表示されます。

ARN TaskSetManager:ステージ3には非常に大きなサイズ(4644 KB)のタスクが含まれています。推奨される最大タスクサイズは100 KBです。

この警告を解決する方法は?サイズを処理する方法はありますか?また、ビッグデータの時間の複雑さに影響しますか?

29
user2959723

@ leo9rコメントの拡張:python rangeではなくsc.rangehttps://spark.Apache.org/docs/1.6.0/api/python/pyspark.html#pyspark.SparkContext.range

したがって、ドライバーからエグゼキューターへの膨大なリストの転送を回避できます。

もちろん、このようなRDDは通常、テスト目的でのみ使用されるため、ブロードキャストされることは望ましくありません。

4

Sparkは、タスクの出荷中に各変数のコピーをネイティブに出荷します。このような変数のサイズが大きい場合は、 ブロードキャスト変数 を使用できます

それでもサイズの問題に直面している場合は、おそらくこのデータ自体がRDDである必要があります

編集:リンクを更新しました

9

一般的な考え方は、PySparkが作成するJavaプロセスはエグゼキューターよりも多く、各プロセスにデータを送信します。プロセスが少なすぎる場合、Javaヒープスペース。

あなたの場合、特定のエラーは、sc.parallelize([...])で作成したRDDがパーティションの数を指定しなかったことです(引数numSlicesdocs を参照)。また、RDDはデフォルトでは小さすぎるパーティションの数に設定されています(単一のパーティションで構成されている可能性があります)。

この問題を解決するには、必要なパーティションの数を指定するだけです。

a = sc.parallelize([...], numSlices=1000)   # and likewise for b

スライスの数を増やして指定すると、警告メッセージに示されているサイズが小さくなります。警告メッセージが表示されなくなるまで、スライスの数を増やします。たとえば、

Stage 0 contains a task of very large size (696 KB). The maximum recommended task size is 100 KB

より多くのスライスを指定する必要があることを意味します。


メモリの問題を処理する際に役立つ可能性のある別のヒント(ただし、これは警告メッセージとは無関係です):デフォルトでは、各エグゼキュータで使用可能なメモリは1 GB程度です。コマンドラインを使用して、たとえば--executor-memory 64G

7
Jealie