这两天在测试环境提交 Spark Streaming 任务时,遇到了一个 JDK 版本问题导致 job 一直提交失败。
我们使用的组件版本:
1Spark 2.1 2Elasticsearch 6.3.2 3JDK1.8.0_162
查看 ApplicationMaster 日志,找到报错信息:
java.lang.UnsupportedClassVersionError: org/elasticsearch/client/RestHighLevelClient : Unsupported major.minor version 52.0
没错,一看便知和 JDK 版本有关系。因为任务是输出到 ES,起初猜测是 ES 对 JDK 要求高,节点环境中的 JDK 低了、不能满足 ES 要求。
还是到 ES 官网查看了下,官网文档针对 ES 6.3.2 版本的 Java 版本建议是这样的: " We recommend installing Java version 1.8.0_131 or a later version in the Java 8 release series. "
对比我们自己使用的 Java 版本 1.8.0_162,是能够满足要求的。
于是便能比较肯定的锁定问题是: Spark自身没有设置好 Java 版本 。这里一般是由于编译打包 Spark 程序时的 Java 版本和运行程序时的 Java 版本不一致导致的。
先来看看我们刚开始提交任务的脚本:
#!/bin/bash export JAVA_HOME=/usr/java/jdk1.8.0_162 spark2-submit / --master yarn / --deploy-mode cluster / --executor-cores 1 / --executor-memory 1g / --driver-memory 1g / --conf spark.dynamicAllocation.maxExecutors=2 / --conf spark.locality.wait.node=0 / --conf spark.executor.userClassPathFirst=true / --conf spark.driver.userClassPathFirst=true / --files app.properties / --jars protobuf-java-3.0.2.jar / --class com.bigdata.note.sink.es.streaming.Sink2TestES / --name Sink2TestES / data-sink-es.jar
看样子我们好像已经设置了任务的 JAVA_HOME,但实际上这里并没有起作用。运行的时候仍然会报上述异常。怎么才能确定任务具体使用的是哪个 JDK 呢,还是要查看 ApplicationMaster 日志:
19/07/19 16:59:10 INFO zookeeper.ZooKeeper: Client environment:java.version=1.7.0_67 19/07/19 16:59:10 INFO zookeeper.ZooKeeper: Client environment:java.vendor=Oracle Corporation 19/07/19 16:59:10 INFO zookeeper.ZooKeeper: Client environment:java.home=/usr/java/jdk1.7.0_67-cloudera/jre
设置 JDK 的正确姿势
经过一番思索,想起只是设置 JAVA_HOME 好像不行,还要在命令行里配置一些 JAVA_HOME 的参数,参考了之前提交任务的脚本,最终找到了设置 JAVA_HOME 的正确方法:
#!/bin/bash spark2-submit / --master yarn / --deploy-mode cluster / --executor-cores 1 / --executor-memory 1g / --driver-memory 1g / --conf spark.yarn.appMasterEnv.JAVA_HOME=/usr/java/jdk1.8.0_162 / --conf spark.executorEnv.JAVA_HOME=/usr/java/jdk1.8.0_162 / --conf spark.dynamicAllocation.maxExecutors=2 / --conf spark.locality.wait.node=0 / --conf spark.executor.userClassPathFirst=true / --conf spark.driver.userClassPathFirst=true / --files app.properties / --jars protobuf-java-3.0.2.jar / --class com.bigdata.note.sink.es.streaming.Sink2TestES / --name Sink2TestES / data-sink-es.jar
设置上面的这两个参数:spark.yarn.appMasterEnv.JAVA_HOME 与 spark.executorEnv.JAVA_HOME,它们的含义分别是指定 Driver 端、Excutor 端的 JDK 路径。通过这样的参数设置,测试下来去掉 export JAVA_HOME 后任务仍然能够正常执行。
其他参考
https://www.iteblog.com/archives/1883.html
1、玩转HBase百亿级数据扫描
2 、 详解Kafka:大数据开发最火的核心技术
3 、 关于NoSQL,看这篇就够了
4、 一份超详细的 Spark 入门介绍
5、 入门教程 | 从安装部署开始学习 Elasticsearch
6、 细数 MQ 那些不得不说的 8 大好处