我有一个程序生成一个DataFrame,它将在其上运行类似
的内容 Select Col1, Col2...
orderBy(ColX) limit(N)
然而,当我最终收集数据时,我发现如果我采取足够大的顶部N,它会导致驱动程序到OOM
另一个观察是,如果我只是排序和顶部,这个问题不会发生。所以只有在同时存在sort和top时才会发生这种情况。
我想知道为什么会发生这种情况?特别是,这两种变换组合真正发生了什么? spark如何使用排序和限制以及下面的相应执行计划来评估查询?
同样好奇的是火花手柄排序和DataFrame和RDD之间的顶级差异?
EDIT, 对不起,我不是指收集, 我原来只是意味着当我调用任何动作来实现数据时,无论是否收集(或任何将数据发送回驱动程序的动作)(所以问题肯定不在于输出大小)
答案 0 :(得分:1)
虽然不清楚为什么在这种特殊情况下失败,但您可能会遇到多个问题:
limit
时,无论n
有多大,它都会将所有数据放在一个分区上。因此,虽然它没有明确地收集它几乎一样糟糕。orderBy
需要使用范围分区进行完全随机播放,这可能会在数据分布偏差时导致不同的问题。collect
结果可能大于驱动程序上可用的内存量时。如果你collect
无论如何都没有多少你可以在这里改进。在一天结束时,驱动程序内存将是一个限制因素,但仍有一些可能的改进:
limit
。collect
替换为toLocalIterator
。orderBy
|> rdd
|> zipWithIndex
|> filter
或者如果确切数量的值不是硬性要求filter
数据直接基于Saving a spark dataframe in multiple parts without repartitioning中显示的近似分布(在Spark 2.0.0+中,有方便的approxQuantile
法)。