从Spark集群中收集数据时出现内存不足错误

时间:2017-08-25 01:35:39

标签: apache-spark memory sparklyr

我知道有很多关于Spark的内存错误的问题,但是我没有找到解决方案。

我有一个简单的工作流程:

  1. 从Amazon S3读入ORC文件
  2. filter下到一小部分行
  3. select列的一小部分
  4. collect进入驱动程序节点(因此我可以在R中执行其他操作)
  5. 当我运行上面然后cache表来激发内存时,它占用的空间<2GB - 与我的集群可用的内存相比很小 - 然后当我尝试{{1时出现OOM错误数据到我的驱动程序节点。

    我尝试过运行以下设置:

    • 具有32核和244GB内存的计算机上的本地模式
    • 具有10 x 6.2 GB执行程序和61 GB驱动程序节点的独立模式

    对于其中的每一项,我都使用了collectexecutor.memorydriver.memory的多种配置来覆盖我可用内存中的所有可能值,但总是我最终在driver.maxResultSize阶段出现内存不足错误;或 collect
    java.lang.OutOfMemoryError: Java heap space,或 java.lang.OutOfMemoryError : GC overhead limit exceeded(表示内存问题的Error in invoke_method.spark_shell_connection(spark_connection(jobj), : No status is returned.错误)。

    根据我对Spark的[有限]理解,在收集之前缓存一个表应强制进行所有计算 - 即如果表在缓存在<2GB之后快乐地坐在内存中,那么我不需要超过2GB将内存收集到驱动程序节点中。

    请注意,this question的答案有一些我尚未尝试的建议,但这些可能会影响性能(例如序列化RDD),所以如果可能的话,请避免使用。

    我的问题:

    1. 如何在缓存后占用如此少空间的数据帧会导致内存问题?
    2. 在我继续讨论可能影响性能的其他选项之前,有什么显而易见的东西可以检查/更改/排除故障以帮助解决问题吗?
    3. 谢谢

      编辑:请注意以下@ Shaido的评论,通过Sparklyr调用sparklyr“强制数据通过在表格上执行cache来加载到内存中”[来自Sparklyr文档] - 即表格应该在内存中,并且在调用count(*)之前运行(我相信)所有计算。

      修改:自从遵循以下建议后的其他一些观察结果:

      • 根据下面的评论,我现在尝试将数据写入csv而不是收集以了解可能的文件大小。此操作会创建一组总计约3GB的csv,并在缓存后运行时仅需2秒。
      • 如果我将collect设置为&lt; 1G,则会收到错误消息,指出序列化RDD的大小为1030 MB,大于driver.maxResultSize。
      • 如果我在调用driver.maxResultSize后在任务管理器中观察内存使用情况,我会看到该用法一直持续到达90GB左右,此时发生OOM错误。 因此无论出于何种原因,用于执行collect操作的RAM量比我尝试收集的RDD大小大约100倍

      编辑下面添加的代码,符合评论中的要求。

      collect

2 个答案:

答案 0 :(得分:4)

当你说收集数据框时,有两件事情发生,

  1. 首先,必须将所有数据写入驱动程序的输出。
  2. 驱动程序必须从所有节点收集数据并保留在其内存中。
  3. 答案:

    如果您只想将数据加载到例程的内存中,count()也是一个将数据加载到执行程序内存中的操作,可供其他进程使用。

    如果你想提取数据,那么在制作数据时,请尝试使用其他属性&#34; - conf spark.driver.maxResultSize = 10g&#34;。

答案 1 :(得分:2)

如上所述,“缓存”不是动作,请检查 RDD Persistence

window.BaseUrl + '/

但是“collect”是一个动作,所有计算(包括“缓存”)将在调用“collect”时启动。

您在独立模式下运行应用程序,这意味着,初始数据加载和所有计算将在同一内存中执行。

数据下载和其他计算用于大多数内存,而不是“收集”。

您可以将“收集”替换为“计数”来检查。