java.lang.OutOfMemoryError Spark DAG包含更多阶段

时间:2017-09-01 23:14:25

标签: java apache-spark memory-management spark-dataframe amazon-emr

我有一个运行sql连接的spark作业。

我将DAG可视化,每次加入时都会产生+5个阶段。无论如何,在DAG有大约40个阶段的阶段之后,下一步总是失败,例如在8次迭代之后,每次5个阶段。

  

线程中的异常" main" java.lang.OutOfMemoryError at   java.lang.AbstractStringBuilder.hugeCapacity(AbstractStringBuilder.java:161)     在   java.lang.AbstractStringBuilder.newCapacity(AbstractStringBuilder.java:155)     在   java.lang.AbstractStringBuilder.ensureCapacityInternal(AbstractStringBuilder.java:125)     在   java.lang.AbstractStringBuilder.append(AbstractStringBuilder.java:448)     在java.lang.StringBuilder.append(StringBuilder.java:136)at   java.lang.StringBuilder.append(StringBuilder.java:131)at   scala.StringContext.standardInterpolator(StringContext.scala:125)at   scala.StringContext.s(StringContext.scala:95)at   org.apache.spark.sql.execution.QueryExecution.toString(QueryExecution.scala:230)     在   org.apache.spark.sql.execution.SQLExecution $ .withNewExecutionId(SQLExecution.scala:54)     在   org.apache.spark.sql.Dataset.withNewExecutionId(Dataset.scala:2788)     在   org.apache.spark.sql.Dataset.org $阿帕奇$火花$ SQL $数据集$$执行$ 1(Dataset.scala:2385)     在   org.apache.spark.sql.Dataset.org $阿帕奇$火花$ SQL $数据集$$收集(Dataset.scala:2392)     在   org.apache.spark.sql.Dataset $$ anonfun $计数$ 1.适用(Dataset.scala:2420)     在   org.apache.spark.sql.Dataset $$ anonfun $计数$ 1.适用(Dataset.scala:2419)     在org.apache.spark.sql.Dataset.withCallback(Dataset.scala:2801)at   org.apache.spark.sql.Dataset.count(Dataset.scala:2419)at   com.samsung.cloud.mopay.linking.controller.PostNotificLinkController.linkPostNotific(PostNotificLinkController.java:51)     在   com.samsung.cloud.mopay.linking.txn.TxnLinking.performTxnLinking(TxnLinking.java:26)     在   com.samsung.cloud.mopay.linking.Linking.processData(Linking.java:199)     在com.samsung.cloud.mopay.linking.Linking.main(Linking.java:72)at   sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)at   sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)     在   sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)     在java.lang.reflect.Method.invoke(Method.java:498)at   org.apache.spark.deploy.SparkSubmit $ .ORG $阿帕奇$火花$部署$ SparkSubmit $$ runMain(SparkSubmit.scala:743)     在   org.apache.spark.deploy.SparkSubmit $ .doRunMain $ 1(SparkSubmit.scala:187)     在org.apache.spark.deploy.SparkSubmit $ .submit(SparkSubmit.scala:212)     在org.apache.spark.deploy.SparkSubmit $ .main(SparkSubmit.scala:126)     在org.apache.spark.deploy.SparkSubmit.main(SparkSubmit.scala)

我用

运行火花
--conf spark.driver.memory=30g 
--conf spark.yarn.driver.memoryOverhead=15g
--conf spark.executor.memory=10g
--conf spark.yarn.executor.memoryOverhead=6g
--conf spark.executor.cores=5

每个节点3个实例(r3.2xlarge)=> 12个执行器实例

3 个答案:

答案 0 :(得分:1)

解决方案是在几个阶段后保留数据。这将启动一个新的执行计划,不会添加到现有计划中,使其变得越来越大,内存不足。

答案 1 :(得分:0)

根本问题是,您一直在对数据框进行许多转换,而没有持久化或破坏其沿袭。

为什么要沿袭/ DAG? Spark使用这些血统来确保其容错能力。您需要根据应用程序和要构建的数据帧之间的容错程度进行权衡。

要避免的方式:

经过几次昂贵的转换后,您可以:

  1. 坚持使用HDFS(只需写入镶木地板)
  2. 经过几个阶段的检查点(spark核心内置的持久存储功能)
  3. 从现有的框架开始创建一个新的数据框架。 (摆脱血统)

答案 2 :(得分:-1)

我可以给你一些想法。在不了解您的数据集(大小和基本统计​​数据)和基本火花配置(并行性)的情况下......这些只是我的最佳猜测:

您的数据集有多大,您的分区有多大/多少分区?尝试使用更多/更小的分区 - 默认的spark.default.parallelism / spark.sql.shuffle.partitions是什么?

也许您的数据集中存在热点?在任何已连接的数据集中是否存在包含大量记录的键?您需要分析您的数据并收集所涉及的所有操作数的一些统计数据以及每个操作数中最常用的连接键(连接可能会使您的数据倍增)。

如果您可以提供更多详细信息,那么我会给您更多有根据的猜测。