heq*_*128 208 out-of-memory apache-spark
我的集群:1个主服务器,11个从服务器,每个节点有6 GB内存.
我的设置:
spark.executor.memory=4g, Dspark.akka.frameSize=512
Run Code Online (Sandbox Code Playgroud)
这是问题所在:
首先,我从HDFS到RDD读取了一些数据(2.19 GB):
val imageBundleRDD = sc.newAPIHadoopFile(...)
Run Code Online (Sandbox Code Playgroud)
其次,在这个RDD上做点什么:
val res = imageBundleRDD.map(data => {
val desPoints = threeDReconstruction(data._2, bg)
(data._1, desPoints)
})
Run Code Online (Sandbox Code Playgroud)
最后,输出到HDFS:
res.saveAsNewAPIHadoopFile(...)
Run Code Online (Sandbox Code Playgroud)
当我运行我的程序时,它显示:
.....
14/01/15 21:42:27 INFO cluster.ClusterTaskSetManager: Starting task 1.0:24 as TID 33 on executor 9: Salve7.Hadoop (NODE_LOCAL)
14/01/15 21:42:27 INFO cluster.ClusterTaskSetManager: Serialized task 1.0:24 as 30618515 bytes in 210 ms
14/01/15 21:42:27 INFO cluster.ClusterTaskSetManager: Starting task 1.0:36 as TID 34 on executor 2: Salve11.Hadoop (NODE_LOCAL)
14/01/15 21:42:28 INFO cluster.ClusterTaskSetManager: Serialized task 1.0:36 as 30618515 bytes in 449 ms
14/01/15 21:42:28 INFO cluster.ClusterTaskSetManager: Starting task 1.0:32 as TID 35 on executor 7: Salve4.Hadoop (NODE_LOCAL)
Uncaught error from thread [spark-akka.actor.default-dispatcher-3] shutting down JVM since 'akka.jvm-exit-on-fatal-error' is enabled for ActorSystem[spark]
java.lang.OutOfMemoryError: Java heap space
Run Code Online (Sandbox Code Playgroud)
任务太多了?
PS:当输入数据大约为225 MB时,每件事情都可以.
我怎么解决这个问题?
sam*_*est 334
我有一些建议:
spark.executor.memory=6g.通过检查UI 确保您使用尽可能多的内存(它会说明您使用了多少内存)spark.storage.memoryFraction.如果你不使用cache()或persist在你的代码中,这也可能是0.它的默认值是0.6,这意味着你的堆只能获得0.4*4g的内存.IME减少内存压力通常会使OOM消失.更新:从火花1.6显然我们将不再需要玩这些值,火花将自动确定它们.String和重度嵌套的结构(如Map嵌套的案例类).如果可能,尝试仅使用原始类型并索引所有非基元,特别是如果您期望大量重复.WrappedArray尽可能选择嵌套结构.或者甚至推出自己的序列化 - 您将获得有关如何有效地将数据备份为字节的最多信息,请使用它!Dataset来缓存您的结构,因为它将使用更高效的序列化.与前一个要点相比,这应被视为黑客攻击.将您的领域知识构建到您的算法/序列化中可以将内存/缓存空间最小化100倍或1000倍,而所有Dataset可能的内存可能是内存中的2x - 5x和磁盘上的10x压缩(镶木地板).http://spark.apache.org/docs/1.2.1/configuration.html
编辑:(所以我可以谷歌自己更容易)以下也表明了这个问题:
java.lang.OutOfMemoryError : GC overhead limit exceeded
Run Code Online (Sandbox Code Playgroud)
Bri*_*ian 52
要向此添加一个通常没有讨论的用例,我将在本地模式下提交Spark应用程序时提出解决方案.spark-submit
您可以在本地模式下运行Spark.在这种非分布式单JVM部署模式中,Spark在同一个JVM中生成所有执行组件 - 驱动程序,执行程序,后端和主服务器.这是使用驱动程序执行的唯一模式.
因此,如果您遇到OOM错误heap,则只需调整driver-memory而不是executor-memory.
这是一个例子:
spark-1.6.1/bin/spark-submit
--class "MyClass"
--driver-memory 12g
--master local[*]
target/scala-2.10/simple-project_2.10-1.0.jar
Run Code Online (Sandbox Code Playgroud)
Tom*_*art 15
看一下在那里设置Java堆大小的启动脚本,看起来你在运行Spark worker之前没有设置它.
# Set SPARK_MEM if it isn't already set since we also use it for this process
SPARK_MEM=${SPARK_MEM:-512m}
export SPARK_MEM
# Set JAVA_OPTS to be able to load native libraries and to set heap size
JAVA_OPTS="$OUR_JAVA_OPTS"
JAVA_OPTS="$JAVA_OPTS -Djava.library.path=$SPARK_LIBRARY_PATH"
JAVA_OPTS="$JAVA_OPTS -Xms$SPARK_MEM -Xmx$SPARK_MEM"
Run Code Online (Sandbox Code Playgroud)
您可以在此处找到要部署脚本的文档.
blu*_*kin 15
你应该增加驱动程序内存.在我的$ SPARK_HOME/conf文件夹中,您应该找到该文件spark-defaults.conf,编辑并设置spark.driver.memory 4000m取决于主服务器上的内存,我认为.这就解决了我的问题,一切顺利
小智 11
您应该配置offHeap内存设置,如下所示:
val spark = SparkSession
.builder()
.master("local[*]")
.config("spark.executor.memory", "70g")
.config("spark.driver.memory", "50g")
.config("spark.memory.offHeap.enabled",true)
.config("spark.memory.offHeap.size","16g")
.appName("sampleCodeForReference")
.getOrCreate()
Run Code Online (Sandbox Code Playgroud)
根据您的计算机RAM可用性为驱动程序提供内存和执行程序内存.如果您仍然面临OutofMemory问题,可以增加offHeap大小.
我在这个问题上受了很多苦,我们使用动态资源分配,我认为它将利用我的群集资源来最适合该应用程序。
但事实是,动态资源分配不会设置驱动程序内存,而是将其保留为默认值1g。
我已经通过将spark.driver.memory设置为适合我的驱动程序内存的数字来解决它(对于32GB内存,我将其设置为18GB)
您可以使用spark提交命令进行设置,如下所示:
spark-submit --conf spark.driver.memory=18gb ....cont
Run Code Online (Sandbox Code Playgroud)
非常重要的说明,根据spark文档,如果您通过代码进行设置,则不会考虑该属性:
Spark属性主要可以分为两种:一种与部署相关,例如“ spark.driver.memory”,“ spark.executor.instances”,在运行时通过SparkConf进行编程设置时,此类属性可能不会受到影响;或者该行为取决于您选择的集群管理器和部署模式,因此建议您通过配置文件或spark-submit命令行选项进行设置;另一个主要与Spark运行时控件有关,例如“ spark.task.maxFailures”,可以用任何一种方式设置这种属性。
小智 5
广义上讲,spark Executor的JVM内存可以分为两部分。Spark内存和用户内存。这由属性控制spark.memory.fraction-值在0到1之间。在Spark应用程序中处理图像或进行内存密集型处理时,请考虑减小spark.memory.fraction。这将使更多的内存可用于您的应用程序工作。Spark可能会溢出,因此它仍将以较少的内存份额工作。
问题的第二部分是分工。如果可能,将数据分成较小的块。较小的数据可能需要较少的内存。但是,如果这不可能,那么您将牺牲内存的计算能力。通常,一个执行程序将运行多个内核。执行程序的总内存必须足以处理所有并发任务的内存需求。如果不能增加执行程序的内存,则可以减少每个执行程序的内核,以便每个任务都可以使用更多的内存。使用1个具有最大可能内存的核心执行程序进行测试,然后不断增加核心,直到找到最佳核心数量。
小智 5
您是否转储了您的主 gc 日志?所以我遇到了类似的问题,我发现 SPARK_DRIVER_MEMORY 只设置了 Xmx 堆。初始堆大小保持为 1G,并且堆大小永远不会扩展到 Xmx 堆。
传递 "--conf "spark.driver.extraJavaOptions=-Xms20g" 解决了我的问题。
ps辅助| grep java,你会看到以下日志:=
24501 30.7 1.7 41782944 2318184 pts/0 Sl+ 18:49 0:33 /usr/ java /latest/bin/ java- cp/opt/spark/conf/:/opt/spark/jars/*- Xmx30g-Xms20g
| 归档时间: |
|
| 查看次数: |
212893 次 |
| 最近记录: |