Spark 应用程序报告内存不足的 Oozie 工作流

Oozie workflow with spark application reports out of memory

我试过使用 spark 程序作为单步执行 Oozie 工作流。 我使用了通过 spark-submit 或 spark-shell(相同的代码)成功执行的 jar:

spark-submit --packages com.databricks:spark-csv_2.10:1.5.0  --master yarn-client --class "SimpleApp"  /tmp/simple-project_2.10-1.1.jar

应用程序不应需要大量资源 – 使用 spark 将单个 csv (<10MB) 加载到配置单元。

工作流是使用 Hue、Oozie 工作流编辑器创建的:

<workflow-app name="Spark_test" xmlns="uri:oozie:workflow:0.5">
    <start to="spark-589f"/>
    <kill name="Kill">
        <message>Action failed, error message[${wf:errorMessage(wf:lastErrorNode())}]</message>
    </kill>
    <action name="spark-589f">
        <spark xmlns="uri:oozie:spark-action:0.2">
            <job-tracker>${jobTracker}</job-tracker>
            <name-node>${nameNode}</name-node>
            <configuration>
                <property>
                    <name>mapreduce.map.java.opts</name>
                    <value>-XX:MaxPermSize=2g</value>
                </property>
            </configuration>
            <master>yarn</master>
            <mode>client</mode>
            <name>MySpark</name>
            <jar>simple-project_2.10-1.1.jar</jar>
              <spark-opts>--packages com.databricks:spark-csv_2.10:1.5.0</spark-opts>
            <file>/user/spark/oozie/jobs/simple-project_2.10-1.1.jar#simple-project_2.10-1.1.jar</file>
        </spark>
        <ok to="End"/>
        <error to="Kill"/>
    </action>
    <end name="End"/>
</workflow-app>

我在 运行 工作流程后得到以下日志:

标准输出:

Invoking Spark class now >>> Invocation of Main class completed <<<

Failing Oozie Launcher, Main class [org.apache.oozie.action.hadoop.SparkMain], exception invoking main(), PermGen space

标准错误:

Exception: java.lang.OutOfMemoryError thrown from the UncaughtExceptionHandler in thread "Yarn application state monitor" Failing Oozie Launcher, Main class [org.apache.oozie.action.hadoop.SparkMain], exception invoking main(), PermGen space

系统日志:

2017-03-14 12:31:19,939 ERROR [main] org.apache.hadoop.mapred.YarnChild: Error running child : java.lang.OutOfMemoryError: PermGen space

请建议应该增加哪些配置参数。

您至少有 2 个选项: 1) 通过将此添加到 workflow.xml:

来增加启动器 MR 作业的 PermGen 大小
<property>
    <name>oozie.launcher.mapreduce.map.java.opts</name>
    <value>-XX:PermSize=512m -XX:MaxPermSize=512m</value>
</property>

在此处查看详细信息:http://www.openkb.info/2016/07/memory-allocation-for-oozie-launcher-job.html

2) 首选方法是使用 Java 8 而不是过时的 Java 7

PermGen 内存是非堆内存,用于存储 class 元数据和字符串常量。如果 class.forname() 或任何其他第三方 JAR 没有 运行 时间 class 加载,它通常不会急剧增长。 如果您在启动应用程序后立即收到此错误消息,则意味着分配的永久代 space 小于应用程序中所有 class 文件实际需要的。

"-XX:MaxPermSize=2g"

您已经为 PermGen 内存设置了 2gb。您可以逐渐增加此值,看看哪个值不会抛出内存错误并保留该值。也可以使用profilers来监控permanent generation的内存使用情况,并设置合适的值。

如果这个错误在运行时间触发,那么可能是由于运行时间class加载或在永久代中过度创建字符串常量。它需要分析您的应用程序以解决问题并为 -XX:MaxPermSize 参数设置正确的值。