欢迎关注Hadoop、Spark、Flink、Hive、Hbase、Flume等大数据资料分享微信公共账号:iteblog_hadoop
  1. 文章总数:978
  2. 浏览总数:11,966,453
  3. 评论:3937
  4. 分类目录:106 个
  5. 注册用户数:6126
  6. 最后更新:2018年12月15日
过往记忆博客公众号iteblog_hadoop
欢迎关注微信公众号:
iteblog_hadoop
大数据技术博客公众号bigdata_ai
大数据猿:
bigdata_ai

如何在Spark、MapReduce和Flink程序里面指定JAVA_HOME

大家在使用Spark、MapReduce 或 Flink 的时候很可能遇到这样一种情况:Hadoop 集群使用的 JDK 版本为1.7.x,而我们自己编写的程序由于某些原因必须使用 1.7 以上版本的JDK,这时候如果我们直接使用 JDK 1.8、或 1.9 来编译我们写好的代码,然后直接提交到 YARN 上运行,这时候会遇到以下的异常:

Exception in thread "main" java.lang.UnsupportedClassVersionError: com/iteblog/mobile/UserMobileInfo : Unsupported major.minor version 52.0
	at java.lang.ClassLoader.defineClass1(Native Method)
	at java.lang.ClassLoader.defineClass(ClassLoader.java:800)
	at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
	at java.net.URLClassLoader.defineClass(URLClassLoader.java:449)
	at java.net.URLClassLoader.access$100(URLClassLoader.java:71)
	at java.net.URLClassLoader$1.run(URLClassLoader.java:361)
	at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
	at java.security.AccessController.doPrivileged(Native Method)
	at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:425)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:358)
	at java.lang.Class.getDeclaredMethods0(Native Method)
	at java.lang.Class.privateGetDeclaredMethods(Class.java:2531)
	at java.lang.Class.getMethod0(Class.java:2774)
	at java.lang.Class.getMethod(Class.java:1663)
	at org.apache.spark.deploy.yarn.ApplicationMaster.startUserApplication(ApplicationMaster.scala:537)
	at org.apache.spark.deploy.yarn.ApplicationMaster.runDriver(ApplicationMaster.scala:319)
	at org.apache.spark.deploy.yarn.ApplicationMaster.run(ApplicationMaster.scala:185)
	at org.apache.spark.deploy.yarn.ApplicationMaster$$anonfun$main$1.apply$mcV$sp(ApplicationMaster.scala:653)
	at org.apache.spark.deploy.SparkHadoopUtil$$anon$1.run(SparkHadoopUtil.scala:69)
	at org.apache.spark.deploy.SparkHadoopUtil$$anon$1.run(SparkHadoopUtil.scala:68)
	at java.security.AccessController.doPrivileged(Native Method)
	at javax.security.auth.Subject.doAs(Subject.java:415)
	at org.apache.hadoop.security.UserGroupInformation.doAs(UserGroupInformation.java:1491)
	at org.apache.spark.deploy.SparkHadoopUtil.runAsSparkUser(SparkHadoopUtil.scala:68)
	at org.apache.spark.deploy.yarn.ApplicationMaster$.main(ApplicationMaster.scala:651)
	at org.apache.spark.deploy.yarn.ApplicationMaster.main(ApplicationMaster.scala)

原因很简单,YARN 集群的 JDK 版本低于我们客户端需要的 JDK 版本.Java 8 class file的版本是52,而 Java 7虚拟机只能支持到51,所以肯定会出现上述异常。那我们该如何解决呢?

首先想到的是升级 YARN 集群上面的 JDK 版本到1.8,但是如果很多人都在使用 YARN 集群,这种操作势必影响很多用户,所以这种方法不适合。那有没有更好的办法?肯定有,要不然就没有这篇文章了。

其实我们可以在提交作业之前设置好相关的环境变量,然后再提交,这时候在YARN上执行这个作业的时候就会使用到我们指定的 JDK ,但是前提是我们必须在 YARN 集群的每台节点安装好相应 JDK 版本。下面我将介绍 Spark 、MapReduce 以及 Flink 中如何指定 JAVA_HOME。

Spark

Spark 中有两种方式:

通过指定SPARK_YARN_USER_ENV

这个很简单,直接通过 SPARK_YARN_USER_ENV 环境变量设置好 YARN 集群 JDK 的路径即可,如下:

export SPARK_YARN_USER_ENV="JAVA_HOME=/home/iteblog/java/jdk1.8.0_25"

设置好之后,然后就可以正常提交 Spark 作业,这时候 Spark 在 YARN 上将会使用 jdk1.8.0_25 运行。但是请记住,SPARK_YARN_USER_ENV 环境变量是很早之前的环境变量,并且早就被遗弃了,所以不推荐使用

通过参数设置

推荐使用的是 spark.executorEnv.JAVA_HOMEspark.yarn.appMasterEnv.JAVA_HOME,这分别为 Spark 的 Executor 和 Driver 指定 JDK 路径,如下:

$SPARK_HOME/bin/spark-submit --master yarn-cluster  \
        --executor-memory 8g \
        --num-executors 80 \
        --queue iteblog \
        --conf "spark.yarn.appMasterEnv.JAVA_HOME=/home/iteblog/java/jdk1.8.0_25" \
        --conf "spark.executorEnv.JAVA_HOME=/home/iteblog/java/jdk1.8.0_25" \
        --executor-cores 1 \
        --class com.iteblog.UserActionParser /home/iteblog/spark/IteblogAction-1.0-SNAPSHOT.jar

当然,你也可以将这个参数写到 $SPARK_HOME/conf/spark_default.conf 文件中。其他的环境变量也可以通过这些设置,比如 spark.executorEnv.MY_BLOG=www.iteblog.com 这样我们就可以从程序里面获取 MY_BLOG 环境变量的值。

MapReduce

我们可以通过 MapReduce 程序里面的 Configuration 设置,如下:

conf.set("mapred.child.env", "JAVA_HOME=/home/iteblog/java/jdk1.8.0_25");
conf.set("yarn.app.mapreduce.am.env", "JAVA_HOME=/home/iteblog/java/jdk1.8.0_25");

Flink 也是支持自定义 JAVA_HOME,我们可以在 $FLINK_HOME/conf/flink-conf.yaml,如下:

env.java.home: /home/iteblog/java/jdk1.8.0_25

注意,上面所说的 JDK 路径全部都是指 YARN 集群的 JDK 路径。

本博客文章除特别声明,全部都是原创!
转载本文请加上:转载自过往记忆(https://www.iteblog.com/)
本文链接: 【如何在Spark、MapReduce和Flink程序里面指定JAVA_HOME】(https://www.iteblog.com/archives/1883.html)
喜欢 (12)
分享 (0)
发表我的评论
取消评论

表情
本博客评论系统带有自动识别垃圾评论功能,请写一些有意义的评论,谢谢!