Scala 内存不足

Scala 内存不足,scala,apache-spark,Scala,Apache Spark,我有一个包含150g txt文件的文件夹(大约700个文件,平均每个200MB) 我正在使用scala处理文件,并最终计算一些聚合统计数据。我认为有两种可能的方法可以做到这一点: 手动循环所有文件,对每个文件进行计算,最后合并结果 将整个文件夹读取到一个RDD,在这个RDD上执行所有操作,并让spark执行所有并行化 我倾向于第二种方法,因为它看起来更干净(不需要特定于并行化的代码),但我想知道我的场景是否适合硬件和数据施加的约束。我有一个工作站,有16个线程和64 GB的RAM(因此,不同

我有一个包含150g txt文件的文件夹(大约700个文件,平均每个200MB)

我正在使用scala处理文件,并最终计算一些聚合统计数据。我认为有两种可能的方法可以做到这一点:

  • 手动循环所有文件,对每个文件进行计算,最后合并结果
  • 将整个文件夹读取到一个RDD,在这个RDD上执行所有操作,并让spark执行所有并行化
我倾向于第二种方法,因为它看起来更干净(不需要特定于并行化的代码),但我想知道我的场景是否适合硬件和数据施加的约束。我有一个工作站,有16个线程和64 GB的RAM(因此,不同处理器核心之间的并行化将严格在本地进行)。以后我可能会用更多的机器来扩展基础设施,但现在我只想专注于调整这一工作站场景的设置

我正在使用的代码: -读取TSV文件,并将有意义的数据提取到(字符串、字符串、字符串)三元组 -然后进行一些过滤、映射和分组 -最后,对数据进行了缩减,并计算了一些聚合

我已经能够用一个文件(~200 MB的数据)运行这段代码,但是我得到一个java.lang.OutOfMemoryError:超出了GC开销限制 和/或添加更多数据时出现Java堆外异常(应用程序中断为6GB的数据,但我希望使用150GB的数据)

我想我必须调整一些参数才能使它工作。如果您能提供有关如何解决此问题的任何提示(如何调试内存需求),我将不胜感激。我尝试增加“spark.executor.memory”并使用较少的内核(合理的做法是每个内核需要一些堆空间),但这并没有解决我的问题


我不需要非常快的解决方案(如果需要,它可以轻松运行几个小时甚至几天)。我也没有缓存任何数据,只是最终将它们保存到文件系统中。如果您认为采用手动并行方法更可行,我也可以这样做。

我和我的团队已经成功地处理了一个csv数据,该数据大小超过1 TB,每台机器的内存为32GB。这在很大程度上取决于你在做什么样的处理以及如何处理

  • 如果重新划分RDD,则需要额外的计算 如果开销超过堆大小,请尝试加载包含更多开销的文件 通过减小中的拆分大小来实现并行化
    TextInputFormat.SPLIT\u MINSIZE
    TextInputFormat.SPLIT\u MAXSIZE
    (如果您使用的是TextInputFormat)来提升 平行性

  • 尝试使用mapPartition而不是map,以便可以处理 分区内的计算。如果计算使用临时 变量或实例,但仍面临内存不足的问题,请尝试 降低每个分区的数据数(增加分区 (数字)

  • 使用增加驱动程序内存和执行器内存限制 spark中的“spark.executor.memory”和“spark.driver.memory” 创建Spark上下文之前的配置


  • 请注意,Spark是一个通用群集计算系统,因此在单机中使用Spark来添加另一个基于代码的透视图(与配置相反)是无效的(IMHO):有时候,最好弄清楚Spark应用程序在什么阶段超出内存,并查看是否可以进行更改以修复问题。当我学习Spark时,我有一个Python Spark应用程序由于OOM错误而崩溃。原因是我将所有结果收集回主控中,而不是让任务保存输出

    例如

    • 失败,出现OOM错误。另一方面,
    processed\u data.saveAsTextFile(输出目录)

    • 很好

    是,PySpark RDD/DataFrame
    collect()
    函数用于将数据集的所有元素(从所有节点)检索到驱动程序节点。我们应该在较小的数据集上使用
    collect()
    ,通常在
    filter()
    group()
    count()
    等之后。检索较大的数据集会导致内存不足。

    如果在独立模式下运行Spark,它将无法工作。您需要在资源管理器上运行应用程序,例如在Hadoop集群上运行的
    Thread
    。在一台机器上运行Thread有意义吗?如果不存在分布式群集,独立模式(正确配置时)是否与群集管理器的工作方式相同?如果不打算使用分布式群集,您将如何在64RAM上安装150G?我正在考虑获取一块数据,对其进行处理,并将部分结果存储在磁盘上(如果需要),继续进行下一个块,直到完成所有操作,最后合并部分结果。@Igor通过大量增加您使用的分区数量,可以产生您想要的效果-即一次处理一点。这个答案列出了您可以尝试的所有事情:您有使用有限内存读取大文件的示例代码吗?特别是如何使用
    TextInputFormat.SPLIT\u MAXSIZE
    mapPartitions
    ?我使用的是
    conf.set(“TextInputFormat.SPLIT\u MAXSIZE”,“512M”)
    ,运气不好。
    for item in processed_data.collect():
       print(item)