我有一个包含150GB的文本文件夹(大约700个文件,平均每个文件200MB左右)。
我使用scala来处理这些文件,并最终计算一些聚合统计数据。我看到两种可能的方法:
- 手动循环遍历所有文件,对于每个文件进行计算并在最后合并结果
- 将整个文件夹读入一个RDD,在单个RDD上执行所有操作,并让spark进行所有并行化
我倾向于采用第二种方法,因为它更加简洁(不需要特定于并行化的代码),但是我想知道我的情况是否符合硬件和数据所施加的限制。我有一台工作站可用,拥有16个线程和64 GB的RAM(因此并行化只能在不同的处理器核之间严格进行)。我以后可能会扩展基础设施,但目前我只想专注于调整这个工作站场景的设置。
我正在使用的代码: - 读取TSV文件,并提取有意义的数据到(String,String,String)三元组中 - 然后进行一些过滤、映射和分组 - 最后,缩小数据,并计算一些聚合数据
我已经能够运行单个文件(大约200MB的数据)的代码,但是当添加更多数据时,我会遇到java.lang.OutOfMemoryError: GC overhead limit exceeded和/或Java out of heap异常(该应用程序使用6GB的数据就会崩溃,但我希望将其用于150GB的数据)。
我猜我需要调整一些参数才能使其正常工作。我会感激任何关于如何解决这个问题(如何调试内存需求)的提示。我已经尝试增加“spark.executor.memory”并使用较少的核心数(理性的推断是每个核心需要一些堆空间),但这没有解决我的问题。
我不需要解决方案非常快(即使需要几个小时甚至几天也可以)。我也没有对数据进行缓存,只是最终保存到文件系统中。如果您认为手动并行化方法更可行,我也可以这样做。