web-dev-qa-db-ja.com

Spark:再パーティションとpartitionByの列引数の順序

考慮される方法(_Spark 2.2.1_):

  1. _DataFrame.repartition_(_partitionExprs: Column*_パラメーターを使用する2つの実装)
  2. _DataFrameWriter.partitionBy_

注:この質問では、これらの方法の違いは問われません。

から docs of partitionBy

指定した場合、出力はHiveパーティションスキームと同様にファイルシステムにレイアウトされます。例として、Datasetを年、次に月で分割すると、ディレクトリレイアウトは次のようになります。

  • 年= 2016 /月= 1 /
  • 年= 2016 /月= 02 /

このことから、列引数の順序がディレクトリレイアウトを決定すると推測します。したがって、それは関連です。

から docs of repartition

パーティションの数として_spark.sql.shuffle.partitions_を使用して、指定されたパーティション式でパーティション化された新しいDatasetを返します。結果のDatasetハッシュパーティションです。

私の現在の理解によると、repartitionは、DataFrameを処理する際の並列度を決定します。この定義では、repartition(numPartitions: Int)の動作は単純ですが、_partitionExprs: Column*_引数をとるrepartitionの他の2つの実装については同じことが言えません。


すべてのことを言って、私の疑問は次のとおりです:

  • partitionByメソッドと同様に、列の順序入力もrepartitionメソッドに関連していますか?
  • 上記の質問に対する答えがの場合
    • いいえ:並列実行のために抽出された各チャンクには、それぞれのと同じデータが含まれていますか? = /// =)group同じ列で_GROUP BY_を使用してSQLクエリを実行しましたか?
    • はいrepartition(columnExprs: Column*)メソッドの動作を説明してください
  • repartitionの3番目の実装で_numPartitions: Int_引数と_partitionExprs: Column*_引数の両方を持つことの関連性は何ですか?
7
y2k-shubham

これら2つの方法の唯一の類似点は、それらの名前です。さまざまな用途に使用され、さまざまなメカニズムがあるため、それらをまったく比較しないでください。

そうは言っても、repartitionは以下を使用してデータをシャッフルします。

  • partitionExprsでは、_spark.sql.shuffle.partitions_を使用する式で使用される列にハッシュパーティショナーを使用します。
  • partitionExprsnumPartitionsを使用すると、前のものと同じように動作しますが、_spark.sql.shuffle.partitions_をオーバーライドします。
  • numPartitionsを使用すると、RoundRobinPartitioningを使用してデータを再配置するだけです。

再パーティション化方法にも関連する列入力の順序は?

です。 hash((x, y))は一般にhash((y, x))と同じではありません。

_df = (spark.range(5, numPartitions=4).toDF("x")
    .selectExpr("cast(x as string)")
    .crossJoin(spark.range(5, numPartitions=4).toDF("y")))

df.repartition(4, "y", "x").rdd.glom().map(len).collect()
_
_[8, 6, 9, 2]
_
_df.repartition(4, "x", "y").rdd.glom().map(len).collect()
_
_[6, 4, 3, 12]
_

並列実行のために抽出された各チャンクには、同じ列でGROUP BYを使用してSQLクエリを実行した場合と同じデータが各グループに含まれていますか?

正確な質問が何であるかに応じて。

関連 DataFrameのパーティショニングを定義する方法は?

7
zero323