作成したばかりの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です。
この警告を解決する方法は?サイズを処理する方法はありますか?また、ビッグデータの時間の複雑さに影響しますか?
@ leo9rコメントの拡張:python range
ではなくsc.range
https://spark.Apache.org/docs/1.6.0/api/python/pyspark.html#pyspark.SparkContext.range 。
したがって、ドライバーからエグゼキューターへの膨大なリストの転送を回避できます。
もちろん、このようなRDDは通常、テスト目的でのみ使用されるため、ブロードキャストされることは望ましくありません。
Sparkは、タスクの出荷中に各変数のコピーをネイティブに出荷します。このような変数のサイズが大きい場合は、 ブロードキャスト変数 を使用できます
それでもサイズの問題に直面している場合は、おそらくこのデータ自体がRDDである必要があります
編集:リンクを更新しました
一般的な考え方は、PySparkが作成するJavaプロセスはエグゼキューターよりも多く、各プロセスにデータを送信します。プロセスが少なすぎる場合、Javaヒープスペース。
あなたの場合、特定のエラーは、sc.parallelize([...])
で作成したRDDがパーティションの数を指定しなかったことです(引数numSlices
、 docs を参照)。また、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
。