Apache spark 如何在Spark SQL中强制执行内存分块排序?

Apache spark 如何在Spark SQL中强制执行内存分块排序?,apache-spark,Apache Spark,拼花文件格式对记录顺序敏感。根据排序顺序,它的列式编码可能会生成非常小的文件。 另一方面,对TB级的输入记录进行排序非常昂贵 比如说,将10GB的数据拆分成块,可以在内存中进行排序,同时生成几乎与整个1TB数据完全排序一样小的拼花文件 在生成拼花地板文件之前,是否可以指示Spark SQL进行分块排序 另一个用例是在编写统一拼花文件之前使用分块排序将许多小拼花文件合并为一个。据我所知,Spark

拼花文件格式对记录顺序敏感。根据排序顺序,它的列式编码可能会生成非常小的文件。 另一方面,对TB级的输入记录进行排序非常昂贵

比如说,将10GB的数据拆分成块,可以在内存中进行排序,同时生成几乎与整个1TB数据完全排序一样小的拼花文件

在生成拼花地板文件之前,是否可以指示Spark SQL进行分块排序


另一个用例是在编写统一拼花文件之前使用分块排序将许多小拼花文件合并为一个。

据我所知,Spark<2.0.0中没有现成的选项。您可以尝试的一件事是在编写之前将
合并
与Hive
排序依据
子句结合起来,这应该具有类似的效果:

val-df:DataFrame=???
val n:Int=//
df.聚结(n)
合并(n).寄存器可清空(“df”)
sqlContext.sql(“从df中选择*按foo,bar排序”).write.parquet(…)

请记住,
排序依据
并不等同于
DataFrame.SORT

Spark 2.0.0引入了
sortBy
bucketBy
方法,后者根据给定列对每个bucket中的输出进行排序,并:

val-df:DataFrame=???
val nBuckets:Int=???
df.write.bucketBy(nBuckets,“foo”).sortBy(“foo”,“bar”).saveAsTable(…)

注意:这似乎仅在使用
saveAsTable
保存拼花文件时起作用,但它似乎不直接支持拼花编写器(
df.write.bucketBy(…).sortBy(…).Parquet(…)
)在
spark-2.0.0-preview
中,据我所知,感谢zero323,sortWithinPartitions只是避免最后的合并排序。但是,每个分区都将对其数据进行完全排序,如果不适合内存,则将使用文件。一般来说,我在哪里可以获得有关bucketBy和2.0.0版的更多信息?
sortWithinPartitions
避免了执行完全排序所需的最终合并和洗牌。据我所知,Spark通常不使用内存排序,因为它不假设单个分区的数据适合内存。我不确定是否有任何特定于SQL的优化在起作用。您可以使用
rdd.mapPartitions
将迭代器转换为本地结构并直接排序。关于
sortBy
我知道的唯一参考是和源代码/测试。
spark-2.2.0
不支持
df.write.bucketBy(…).sortBy(…).parquet(…)
但提出适当的例外。
df.coalesce(n).sortWithinPartitions($"foo", $"bar").write.parquet(...)