2016-07-27 143 views
1

我有一个计划采取产生,并会运行类似数据帧排序依据Spark中

Select Col1, Col2... 
    orderBy(ColX) limit(N) 

但是一个数据帧,当我收集结束的数据,我觉得这是造成驱动程序到OOM,如果我拿足够大的顶部N

另一种观察是,如果我只是做排序和顶部,这个问题不会发生。所以这种情况只有在排序和排名同时出现时才会发生。

我想知道为什么会发生?特别是,这两种转换组合下面真正发生了什么? Spark如何通过排序和限制来评估查询,以及下面的相应执行计划是什么?

也只是好奇的火花处理排序和DataFrame和RDD之间的顶部不同?

编辑, 对不起,我不是故意的收集, 我原来只是意味着,当我打电话的任何行动兑现的数据,不管它是否被收集(或任何动作将数据发送回驱动程序)或不(所以,问题绝对不是在输出尺寸)

+0

我建议你在你的问题中添加代码。对于OOM错误通常是驱动程序方面。但没有真正的代码很难说。 –

回答

1

虽然目前尚不清楚为什么这种失败,在这个特殊的情况下,有多个问题,你可能会遇到:

  • 当您使用limit它只是把所有数据在一个分区上,无论多大的n是。所以虽然没有明确地收集它几乎一样糟糕。
  • 最重要的是,orderBy需要一个完整的随机范围划分,当数据分布偏斜时会导致不同的问题。
  • 最后,当collect结果可能大于驱动程序上可用的内存量时。

如果你collect无论如何你没有太多可以改善的地方。在一天结束时驱动程序的内存将是一个限制因素,但仍有一些可能的改进:

  • 首先不要使用limit
  • collect替换为toLocalIterator
  • 兼用orderBy |>rdd |>zipWithIndex |>filter或者如果值的精确的数字不是硬性要求filter数据直接基于近似的分布,如图中Saving a spark dataframe in multiple parts without repartitioning(火花2.0.0+有方便的方法approxQuantile) 。