You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Oozie运行含HiveContext的Spark Scala应用报PermGen内存溢出错误

问题:Oozie运行含HiveContext的Spark Scala应用时出现PermGen内存溢出

环境信息

  • CDH5.13 Quickstart VM(20G内存),已将Java 7升级至Java 8
  • Spark 1.6.0,Scala 2.10.5
  • Oozie集成Spark运行,其他无HiveContext的Spark应用可正常执行

应用代码与配置

Scala应用代码

import org.apache.spark.{SparkConf, SparkContext}
import org.apache.spark.rdd.RDD
object ThirdApp {
  def main(args: Array[String]) {
    val conf = new SparkConf().setAppName("Third Application")
    val sc = new SparkContext(conf)
    val sqlContext = new org.apache.spark.sql.hive.HiveContext(sc)
    import sqlContext.implicits._
    sqlContext.sql("CREATE TABLE IF NOT EXISTS default.src (key INT, value STRING)")
  }
}

sbt配置文件

name := "Third Project"
version := "1.0"
scalaVersion := "2.10.5"
libraryDependencies ++= Seq(
  "org.apache.spark" %% "spark-core" % "1.6.0",
  "org.apache.spark" %% "spark-hive" % "1.6.0"
)

Oozie Workflow配置(workflow.xml)

<workflow-app name="spark-scala" xmlns="uri:oozie:workflow:0.5">
  <start to="spark-5a6a"/>
  <kill name="Kill">
    <message>Action failed, error message[${wf:errorMessage(wf:lastErrorNode())}]</message>
  </kill>
  <action name="spark-5a6a">
    <spark xmlns="uri:oozie:spark-action:0.2">
      <job-tracker>${jobTracker}</job-tracker>
      <name-node>${nameNode}</name-node>
      <master>local</master>
      <mode>client</mode>
      <name>MySpark</name>
      <class>ThirdApp</class>
      <jar>third-project_2.10-1.0.jar</jar>
      <file>/user/cloudera/oozie-spark/third-project_2.10-1.0.jar#third-project_2.10-1.0.jar</file>
    </spark>
    <ok to="End"/>
    <error to="Kill"/>
  </action>
  <end name="End"/>
</workflow-app>

job.properties配置

oozie.use.system.libpath=True
send_email=False
dryrun=False
nameNode=hdfs://quickstart.cloudera:8020
jobTracker=quickstart.cloudera:8032
security_enabled=False

问题描述

该应用通过Spark Shell提交可正常运行,能成功创建Hive表,但通过Oozie运行时抛出PermGen空间内存溢出错误。此前运行不含HiveContext的Spark应用在Oozie中均无异常。

已尝试的解决方法:

  • 在mapred-site.xml中增加Map/Reduce内存配置
  • 在Cloudera Manager中调整Java堆内存
  • 设置Gateway默认组
  • 在workflow中添加--driver-memory 5G参数

但以上方法均未解决问题,请求帮助。


解决方案:针对性调整Oozie Spark Action的JVM元空间参数

首先得提一句:你已经升级到Java 8了,但Java 8里早就用Metaspace替代了PermGen,不过Oozie的Spark Action可能默认还带着老的PermGen配置,再加上HiveContext要加载一大堆类,这就触发了内存溢出的问题。试试下面这些步骤:

1. 给Spark Action加上JVM元空间参数

直接在workflow.xml的<spark>节点里加<spark-opts>标签,把Metaspace的大小配置上——因为你用Java 8,重点调这个:

<spark xmlns="uri:oozie:spark-action:0.2">
  <!-- 保留你原来的所有配置 -->
  <job-tracker>${jobTracker}</job-tracker>
  <name-node>${nameNode}</name-node>
  <master>local</master>
  <mode>client</mode>
  <name>MySpark</name>
  <class>ThirdApp</class>
  <jar>third-project_2.10-1.0.jar</jar>
  <file>/user/cloudera/oozie-spark/third-project_2.10-1.0.jar#third-project_2.10-1.0.jar</file>
  <!-- 新增这行JVM参数配置 -->
  <spark-opts>--driver-java-options "-XX:MaxMetaspaceSize=1G -XX:MetaspaceSize=512M" --executor-java-options "-XX:MaxMetaspaceSize=1G -XX:MetaspaceSize=512M"</spark-opts>
</spark>

要是你的环境里某些组件还在依赖PermGen(比如CDH的老配置),就换成PermGen的参数:

<spark-opts>--driver-java-options "-XX:MaxPermSize=1G -XX:PermSize=512M" --executor-java-options "-XX:MaxPermSize=1G -XX:PermSize=512M"</spark-opts>

2. 检查Oozie的共享库是否完整

你设置了oozie.use.system.libpath=True,得确保Oozie的Spark共享库包含了Hive的相关依赖。可以去Cloudera Manager里查Oozie的Spark共享库状态,或者手动把Hive的JAR包放到Oozie的Spark lib目录(一般是HDFS上的/user/oozie/share/lib/lib_<timestamp>/spark路径)。

3. 把Driver内存和JVM参数一起配置

你之前试过--driver-memory 5G,但最好把它和元空间参数放在同一个<spark-opts>里,确保参数能正确传递给Spark:

<spark-opts>--driver-memory 5G --driver-java-options "-XX:MaxMetaspaceSize=1G" --executor-memory 2G --executor-java-options "-XX:MaxMetaspaceSize=1G"</spark-opts>

4. 调整Oozie自身的JVM配置

在Cloudera Manager里找到Oozie服务的配置,找到Oozie Server Advanced Configuration Snippet (Safety Valve) for oozie-env.sh,加上这行:

export CATALINA_OPTS="-XX:MaxMetaspaceSize=1G -XX:MetaspaceSize=512M $CATALINA_OPTS"

这是给Oozie自己的JVM加元空间,避免它调度任务时自己先内存不够。

为啥只有HiveContext会出这问题?

因为HiveContext要加载超多类——Hive客户端、JDBC驱动、各种序列化类,这些都会占满元空间(或者PermGen)。直接用Shell跑的时候,Spark Shell的默认JVM参数已经做了优化,所以没问题;但Oozie调用Spark时,默认的JVM参数没考虑这么多类的加载需求,就溢出了。


内容的提问来源于stack exchange,提问作者El Mehdi OUAFIQ

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.11 09:11:30