我有两个大的csv文件由其中一列预先排序。有没有办法使用这样一个事实:它们已经被排序以更快地获得新的排序RDD,而没有再次完全排序?
答案 0 :(得分:1)
简短的回答:不,当使用Apache Spark提供的排序工具时,没有办法利用两个输入RDD已经排序的事实。
答案很长:在某些条件下,可能有比使用sortBy
或sortByKey
更好的方式。
最明显的情况是输入RDD已经排序并表示不同的范围。在这种情况下,简单地使用rdd1.union(rdd2)
是组合输入RDD的最快(几乎零成本)方式,假设rdd1
中的所有元素都位于rdd2
中的所有元素之前(根据选择订购)。
当输入RDD的范围重叠时,事情变得更加棘手。假设目标RDD只有一个分区,在两个RDD上使用toLocalIterator
然后手动进行合并可能是有效的。如果结果必须是RDD,则可以在自定义RDD类型的compute
方法内执行此操作,处理输入RDD并生成输出。
当输入很大并且因此包含许多分区时,事情变得更加棘手。在这种情况下,您可能还需要输出RDD中的多个分区。您可以使用前面提到的自定义RDD,但创建多个分区(使用RangePartitioner
)。每个分区将覆盖不同的元素范围(在最佳情况下,这些范围将覆盖输出的大致相同大小的部分)。
这个棘手的部分是避免在compute
内多次处理完整的输入RDD。当输入RDD使用filterByRange
时,可以使用OrderedRDDFunctions
中的RangePartitioner
来有效避免这种情况。当他们不使用RangePartitioner
,但您知道分区是在内部排序并且还具有全局顺序时,您首先需要通过实际探测数据来找出这些分区所涵盖的有效范围。
由于多分区案例相当复杂,我会检查自定义排序是否真的比仅使用sortBy
或sortByKey
更快。 sortBy
和sortByKey
的逻辑针对混洗过程(在节点之间传输数据)进行了高度优化。出于这个原因,很可能在很多情况下这些方法比定制逻辑更快,即使定制逻辑可能是O(n),而sortBy
/ sortByKey
可以是O(n log(n))充其量。
如果您有兴趣了解Apache Spark使用的改组逻辑的更多信息,可以使用article解释基本概念。