Spark SQL HiveContext
を使用してHiveテーブルからデータをロードし、HDFSにロードする必要があります。デフォルトでは、SQL出力からのDataFrame
には2パーティション。より多くの並列処理を行うには、SQLからより多くのパーティションが必要です。HiveContex
tには、パーティションパラメータの数を取得するオーバーロードメソッドはありません。
RDDを再パーティション化すると、シャッフルが発生し、処理時間が長くなります。
>
val result = sqlContext.sql("select * from bt_st_ent")
以下のログ出力があります。
Starting task 0.0 in stage 131.0 (TID 297, aster1.com, partition 0,NODE_LOCAL, 2203 bytes)
Starting task 1.0 in stage 131.0 (TID 298, aster1.com, partition 1,NODE_LOCAL, 2204 bytes)
SQL出力のパーティションサイズを増やす方法はありますか。
スパーク<2.0:
Hadoop構成オプションを使用できます。
mapred.min.split.size
。mapred.max.split.size
ファイルシステムに基づくフォーマット*のパーティションサイズを制御するHDFSブロックサイズ。
val minSplit: Int = ???
val maxSplit: Int = ???
sc.hadoopConfiguration.setInt("mapred.min.split.size", minSplit)
sc.hadoopConfiguration.setInt("mapred.max.split.size", maxSplit)
Spark 2.0 +:
spark.sql.files.maxPartitionBytes
構成を使用できます。
spark.conf.set("spark.sql.files.maxPartitionBytes", maxSplit)
どちらの場合も、これらの値は特定のデータソースAPIで使用されていない可能性があるため、使用する形式のドキュメント/実装の詳細を常に確認する必要があります。
*他の入力フォーマットは異なる設定を使用できます。例を見る
さらに、Datasets
から作成されたRDDs
は、親からパーティションレイアウトを継承します。
同様に、バケット化されたテーブルは、メタストアで定義されたバケットレイアウトを使用し、バケットとDataset
パーティションの間に1:1の関係があります。
非常に一般的で痛みを伴う問題。データを均一なパーティションに分散するキーを探す必要があります。 DISTRIBUTE BY
およびCLUSTER BY
演算子を使用してsparkに行をパーティションにグループ化することができます。これにより、クエリ自体にオーバーヘッドが発生しますが、均等なサイズのパーティション Deepsense には、これに関する非常に優れたチュートリアルがあります。
SQLがシャッフルを実行する場合(たとえば、結合やある種のグループ化がある場合)、 'spark.sql.shuffle.partitions'プロパティを設定して、パーティションの数を設定できます。
sqlContext.setConf( "spark.sql.shuffle.partitions", 64)
Fokkoの提案をフォローアップすると、ランダム変数を使用してクラスター化できます。
val result = sqlContext.sql("""
select * from (
select *,random(64) as Rand_part from bt_st_ent
) cluster by Rand_part""")