Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/apache-spark/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Scala 内存不足错误的Spark配置_Scala_Apache Spark - Fatal编程技术网

Scala 内存不足错误的Spark配置

Scala 内存不足错误的Spark配置,scala,apache-spark,Scala,Apache Spark,群集设置- Driver has 28gb Workers have 56gb each (8 workers) 配置- spark.memory.offHeap.enabled true spark.driver.memory 20g spark.memory.offHeap.size 16gb spark.executor.memory 40g 我的工作- //myFunc just takes a string s and does some transformations on it

群集设置-

Driver has 28gb
Workers have 56gb each (8 workers)
配置-

spark.memory.offHeap.enabled true
spark.driver.memory 20g
spark.memory.offHeap.size 16gb
spark.executor.memory 40g
我的工作-

//myFunc just takes a string s and does some transformations on it, they are very small strings, but there's about 10million to process.


//Out of memory failure
data.map(s => myFunc(s)).saveAsTextFile(outFile)

//works fine
data.map(s => myFunc(s))
另外,我将spark从我的程序中解聚/删除,它在一台具有56gb ram的服务器上完成得很好(成功地保存到一个文件)。这表明它只是一个spark配置问题。我回顾了我目前拥有的配置,这些配置似乎是我工作所需的全部更改。我还应该换什么

更新-

资料-

val fis: FileInputStream = new FileInputStream(new File(inputFile))
val bis: BufferedInputStream = new BufferedInputStream(fis);
val input: CompressorInputStream = new CompressorStreamFactory().createCompressorInputStream(bis);
br = new BufferedReader(new InputStreamReader(input))
val stringArray = br.lines().toArray()
val data = sc.parallelize(stringArray)
注意-这不会导致任何内存问题,即使它的效率非常低。我无法使用spark读取,因为它会抛出一些EOF错误

myFunc,我不能发布它的代码,因为它很复杂。但基本上,输入字符串是一个删除字符串,它执行一些删除器替换、日期/时间规范化等操作。输出字符串的大小与输入字符串的大小大致相同


此外,它还适用于较小的数据大小,并且输出是正确的,与输入数据文件的大小大致相同,这是应该的。

如果您在映射之前和之后在程序中添加更多详细信息,将会有所帮助。 第二个命令(仅映射)不会执行任何操作,除非触发操作。您的文件可能未分区,驱动程序正在执行此工作。下面应该将数据均匀地发送到工作节点,并保护单个节点上的OOM。不过,这会导致数据混乱

在查看代码后更新解决方案,这样做会更好

val data = sc.parallelize(stringArray).repartition(8)
data.map(s => myFunc(s)).saveAsTextFile(outFile)

您当前的解决方案没有利用spark。将整个文件加载到内存中的数组中,然后使用sc.parallelize将其分发到RDD中。这是对内存的极大浪费(即使没有火花),当然也会导致大文件内存不足的问题

相反,使用
sc.textFile(filePath)
创建RDD。然后spark能够智能地读取和处理分块的文件,因此一次只需要将文件的一小部分存储在内存中。您还可以通过这种方式利用并行性,因为spark将能够以并行方式读取和处理文件,无论您有多少执行器和corse,而不需要在一台机器上的单个线程上读取整个文件


假设myFunc一次只能查看一行,那么这个程序的内存占用应该非常小。

什么是
数据以及它是如何生成的?
myFunc
的定义是什么?
myFunc
中可能存在导致内存问题的内容,但更可能的问题是用于创建
数据的其他转换之一。不看代码是不可能说出的。所以我们需要查看源文件中的完整流。工作正常的那一个这样做是因为它什么都不做。请记住,在您运行操作之前,spark中不会发生任何事情。@puhlen使用信息更新了主要帖子。我在帖子中添加了一个更新,提供了更多信息。不过我会试试的,谢谢!是的,我试过了,我放了一张便条,说这是不可能的,因为我有一些EOF错误,输入文件无论如何都不能修改。但如果我能让它工作起来,这能解决我的问题吗?因为读取整个文件本身不会导致内存错误。同样是的,
MyFunc
一次只接收一行,并且有1500万~lines@jayjay93是的,如果您使用
textfile
让它工作,它应该可以解决您的问题。如果需要将大型数据集加载到数组中,还可以增加驱动程序内存,然后使用
sc.parallelize
。如果程序在没有火花的情况下运行良好,那么为什么不这样做呢。根据您的描述,您可能可以编写一个高效的程序,在一台机器上使用不到100MB的ram来完成任务。我不怀疑您,但在我尝试解决文本文件问题之前,我可以将整个文件存储在我的驱动程序中,同时只使用20%的内存。那么,为什么“智能读取”文件可以帮助我避免内存不足呢?驱动程序上的1500万项数组根本没有引起任何问题,我已经测试过了///////////////