实木复合地板文件格式对记录的顺序敏感。它的列编码可能会根据排序顺序产生较小的文件。另一方面,对TB级的输入记录进行排序非常昂贵。
分成几块,例如10GB,可以在内存中进行排序,同时生成几乎一样小的木地板文件,就好像整个1 TB已完全排序一样。
是否可以指示Spark SQL在生成镶木文件之前进行分块排序?
另一个用例是在编写统一的Parquet文件之前使用分块排序将许多小型Parquet文件合并为一个。
据我所知,Spark <2.0.0中没有开箱即用的此类选项。您可以尝试做的一件事是在编写之前coalesce
与HiveSORT BY
子句结合使用,这应该会产生类似的效果:
val df: DataFrame = ???
val n: Int = ??? //
df.coalesce(n)
df.coalesce(n).registerTempTable("df")
sqlContext.sql("SELECT * FROM df SORT BY foo, bar").write.parquet(...)
或者
df.coalesce(n).sortWithinPartitions($"foo", $"bar").write.parquet(...)
请记住,这SORT BY
并不等同于DataFrame.sort
。
引入了Spark 2.0.0sortBy
和bucketBy
方法,其中后者按给定的列对每个存储桶中的输出进行排序,并应支持Parquet:
val df: DataFrame = ???
val nBuckets: Int = ???
df.write.bucketBy(nBuckets, "foo").sortBy("foo", "bar").saveAsTable(...)
注意:这似乎仅在与保存Parquet文件时有效,saveAsTable
但它似乎不支持直接(df.write.bucketBy(...).sortBy(...).parquet(...)
)中的Parquet writer spark-2.0.0-preview
。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句