如何在Spark中将镶木地板文件拆分为多个分区?

时间:2014-11-28 18:37:54

标签: scala apache-spark parquet

所以我只有一个镶木地板文件,我正在阅读Spark(使用SQL的东西),我希望它能用100个分区进行处理。我已经尝试将spark.default.parallelism设置为100,我们也尝试将拼花的压缩更改为无(来自gzip)。无论我们做什么,火花作业的第一阶段只有一个分区(一旦发生洗牌,它就被重新划分为100,此后显然事情要快得多)。

现在根据一些消息来源(如下所示),镶木地板应该是可拆分的(即使使用gzip!),所以我非常困惑,并且会喜欢一些建议。

https://www.safaribooksonline.com/library/view/hadoop-application-architectures/9781491910313/ch01.html

我使用spark 1.0.0,显然spark.sql.shuffle.partitions的默认值是200,所以它不可能。事实上,并行性的所有默认值都远远超过1,所以我不明白发生了什么。

5 个答案:

答案 0 :(得分:9)

您应该使用较小的块大小编写镶木地板文件。默认值为每块128Mb,但可以通过在编写器中设置parquet.block.size配置来配置。

convention,如果你想深入了解细节。

块大小是你可以读取的镶木地板文件的最小数据量,这个数据在逻辑上是可读的(因为镶木地板是柱状的,你不能只是按行分割或像这样的小事),所以你不能拥有比输入块更多的读取线程。

答案 1 :(得分:1)

也许你的镶木地板文件只需要一个HDFS块。创建一个包含许多HDFS块并加载它的大型镶木地板文件

val k = sc.parquetFile("the-big-table.parquet")
k.partitions.length

您将看到与HDFS块相同数量的分区。这对我来说很好(spark-1.1.0)

答案 2 :(得分:1)

您已经提到要在写入镶木地板时控制分布。当您从RDD创建镶木地板时,会保留RDD的分区。因此,如果您创建RDD并指定100个分区,并且从带有镶木地板格式的数据框中,那么它将写入100个单独的镶木地板文件到fs。 对于阅读,您可以指定spark.sql.shuffle.partitions参数。

答案 3 :(得分:0)

要实现这一点,您应该使用SparkContext来设置Hadoop配置(sc.hadoopConfiguration)属性mapreduce.input.fileinputformat.split.maxsize

通过将此属性设置为低于hdf​​s.blockSize的值,您将获得与拆分​​数量一样多的分区。

例如:
hdfs.blockSize = 134217728(128MB)时,
并读取一个文件,其中只包含一个完整的块,
mapreduce.input.fileinputformat.split.maxsize = 67108864(64MB)

然后会有两个分区将被读入。

答案 4 :(得分:0)

新的做法(Spark 2.x)正在设置

spark.sql.files.maxPartitionBytes

来源:https://issues.apache.org/jira/browse/SPARK-17998(官方文档还不正确,错过了.sql)

根据我的经验,Hadoop设置不再有效。