我有一个实木复合地板文件/df
保存在具有120个分区的hdfs中。 hdfs上每个分区的大小约为43.5 M。
总大小
hdfs dfs -du -s -h /df
5.1 G 15.3 G /df
hdfs dfs -du -h /df
43.6 M 130.7 M /df/pid=0
43.5 M 130.5 M /df/pid=1
...
43.6 M 130.9 M /df/pid=119
我想将该文件加载到Spark中并保持相同数量的分区。 但是,Spark会自动将文件加载到60个分区中。
df = spark.read.parquet('df')
df.rdd.getNumPartitions()
60
HDFS设置:
'parquet.block.size'
未设置。
sc._jsc.hadoopConfiguration().get('parquet.block.size')
不返回任何内容。
'dfs.blocksize'设置为128。
float(sc._jsc.hadoopConfiguration().get("dfs.blocksize"))/2**20
返回
128
将这些值中的任何一个更改为较低值都不会导致镶木地板文件加载到hdfs中相同数量的分区中。
例如:
sc._jsc.hadoopConfiguration().setInt("parquet.block.size", 64*2**20)
sc._jsc.hadoopConfiguration().setInt("dfs.blocksize", 64*2**20)
我意识到43.5 M远低于128M。但是,对于此应用程序,我将立即完成许多转换,这将导致120个分区中的每个分区更接近128 M。
我试图避免自己在加载后不得不重新分区到应用程序中。
是否有一种方法可以强制Spark使用与hdfs中存储的分区数量相同的分区来加载镶木地板文件?
答案 0 :(得分:0)
首先,我将从检查Spark如何将数据拆分为分区开始。 默认情况下,它取决于数据和集群的性质和大小。 本文应该为您提供答案,为什么您的数据帧会被加载到60个分区中:
通常-它的 Catalyst 负责所有优化(包括分区数),因此,除非确实有充分的理由进行自定义设置,否则我将让它完成工作。如果您使用的任何转换范围很广,Spark都会反洗数据。
答案 1 :(得分:0)
我可以使用(class contact_info).
属性将分区大小保持在导入时所需的位置。
spark.sql.files.maxPartitionBytes
属性的Other Configuration Options documentation状态:
读取文件时打包到单个分区中的最大字节数。仅当使用基于文件的源(例如Parquet,JSON和ORC)时,此配置才有效。
示例(其中spark.sql.files.maxPartitionBytes
是有效的spark
)
SparkSession
要控制转换期间的分区数量,我可以设置documentation的状态spark.conf.set("spark.sql.files.maxPartitionBytes", 67108864) ## 64Mbi
:
配置在对联接或聚集的数据进行混排时要使用的分区数。
示例(其中spark.sql.shuffle.partitions
是有效的spark
)
SparkSession
另外,我可以设置Execution Behavior documentation的spark.conf.set("spark.sql.shuffle.partitions", 500)
:
未由用户设置时,通过诸如join,reduceByKey和parallelize等转换返回的RDD中的默认分区数。
示例(其中spark.default.parallelism
是有效的spark
)
SparkSession