web-dev-qa-db-ja.com

Spark= partition(ing)はHDFSのファイルに対してどのように機能しますか?

私は、Apache Spark HDFSを使用するクラスターで作業しています。私が理解している限り、HDFSはデータノードでファイルを配布しています。 、パーティションに分割されます。

rdd = SparkContext().textFile("hdfs://.../file.txt") 

apache Sparkから。 rddは現在、ファイルシステム上の「file.txt」と同じパーティションを自動的に作成していますか?電話をかけるとどうなりますか

rdd.repartition(x)

ここで、x> hdfsが使用するパーティションはどこですか? Sparkはhdfsのデータを物理的に再配置してローカルで動作しますか?

例:30GBのテキストファイルをHDFSシステムに配置し、10個のノードに配布しています。 Spark a)同じ10パーティトンを使用しますか?およびb)repartition(1000)を呼び出したときにクラスター全体で30GBをシャッフルしますか?

45
Degget

SparkはHDFSからファイルを読み込むと、単一の入力分割に対して単一のパーティションを作成します。入力分割は、このファイルの読み込みに使用されるHadoop InputFormatによって設定されます。たとえば、 textFile()を使用すると、HadoopではTextInputFormatになり、HDFSの単一ブロックに対して単一のパーティションが返されます(ただし、パーティション間の分割は行分割ではなく、行分割で行われます正確なブロック分割)、圧縮テキストファイルがない場合、圧縮ファイルの場合は、単一ファイルに対して単一パーティションを取得します(圧縮テキストファイルは分割できないため)。

rdd.repartition(x)を呼び出すと、Nにあるrddパーティションから、必要なxパーティションへのデータのシャッフルを実行します。ラウンドロビン方式で行われます。

HDFSに30GBの非圧縮テキストファイルが保存されている場合、デフォルトのHDFSブロックサイズ設定(128MB)で235ブロックに保存されます。つまり、このファイルから読み取るRDDには235パーティションがあります。 repartition(1000)を呼び出すと、RDDはrepartitionedとマークされますが、実際には、このRDDの上でアクションを実行する場合にのみ1000パーティションにシャッフルされます(遅延実行の概念)

80
0x0FFF

HDFSのブロックをSparkパーティションとしてのワーカー)にロードする方法」のスナップショットを次に示します。

この画像では、4つのHDFSブロックがSpark 3つのワーカーメモリ内のパーティションとしてロードされます

Dataset in HDFS broken into partitions


例:30GBのテキストファイルをHDFSシステムに配置し、10個のノードに配布しています。

火花

a)同じ10個のパーティションを使用しますか?

Sparkは同じ10個のHDFSブロックをワーカーメモリにパーティションとしてロードします。 GBファイルのブロックサイズは3 GBでなければなりません 10パーティション/ブロックを取得するには(デフォルトの設定で)

b)repartition(1000)を呼び出したときにクラスター全体で30GBをシャッフルしますか?

はい、Spark=ワーカーメモリ内に1000個のパーティションを作成するために、ワーカーノード間でデータをシャッフルします。

注意:

HDFS Block -> Spark partition   : One block can represent as One partition (by default)
Spark partition -> Workers      : Many/One partitions can present in One workers 
11
mrsrinivas

Spark-sqlでバケット化されていないHDFSファイル(パーケットなど)を読み取る場合、DataFrameパーティションの数_df.rdd.getNumPartitions_は次の要因に依存します。

  • _spark.default.parallelism_(アプリケーションで使用可能な#coresに大まかに変換されます)
  • _spark.sql.files.maxPartitionBytes_(デフォルト128MB)
  • _spark.sql.files.openCostInBytes_(デフォルト4MB)

パーティション数の概算は次のとおりです。

  • すべてのデータを並行して読み取るのに十分なコアがある場合(つまり、データの128MBごとに少なくとも1つのコア)

    AveragePartitionSize ≈ min(4MB, TotalDataSize/#cores) NumberOfPartitions ≈ TotalDataSize/AveragePartitionSize

  • 十分なコアがない場合、

    _AveragePartitionSize ≈ 128MB NumberOfPartitions ≈ TotalDataSize/AveragePartitionSize_

正確な計算はやや複雑で、FileSourceScanExecのコードベースで見つけることができます。 here を参照してください。

10
Apoorve Dave

@ 0x0FFFへの追加HDFSから入力ファイルとして取得した場合、このrdd = SparkContext().textFile("hdfs://.../file.txt")のように計算され、_rdd.getNumPatitions_を実行するとMax(2, Number of HDFS block)になります。私は多くの実験を行い、結果としてこれを見つけました。再度明示的にrdd = SparkContext().textFile("hdfs://.../file.txt", 400)を実行してパーティションとして400を取得するか、_rdd.repartition_で再パーティション化するか、rdd.coalesce(10)で10に減らすこともできます。

6
ChikuMiku