最近项目要用到大数据,边学边搞项目。一个坑接着一个坑地踩,好在头铁,总能柳暗花明。
spark-submit 提交任务到 yarn 集群执行官方资料写的很清楚。如果是用脚本方式执行看看说明分分钟搞定的。可偏偏好死不死,设计的方案是在 spring boot 项目中执行 spark-submit。其实就是找 java 代码执行 spark-submit 的 api,但就这个东东,虐我好几天。
有两种方式:
-
使用 SparkLauncher 提交,该方法需要提前设定 SPARK_HOME,我感觉他是直接将任务交到了spark,而没有通过 yarn。个人理解的,可能不正确,I am new to spark。这个博客里面的 demo 是 work 的。
-
将任务提交到 yarn。我们项目定的就是这种方案。不停地找,不停地试,不停地被虐… 好在头铁。
国内大多数伙伴写的代码都源自这篇博客。里面的代码在 spark 1.6 上是 work 的,现在都 spark2.x 甚至 3.x 了,api 已经变了。所以会出现下面的报错:
INFO Client: Retrying connect to server: 0.0.0.0/0.0.0.0:8032. Already tried 0 time(s); retry policy is RetryUpToMaximumCountWithFixedSleep(maxRetries=10, sleepTime=1000 MILLISECONDS) 15/08/05 14:06:12 INFO Client: Retrying connect to server: 0.0.0.0/0.0.0.0:8032. Already tried 1 time(s); retry policy is RetryUpToMaximumCountWithFixedSleep(maxRetries=10, sleepTime=1000 MILLISECONDS)
很明显,yarn 的配置有问题,java 代码在执行 spark-submit 时候找不到 yarn。所以一直在尝试连接,连不上,再尝试,还连不上…,那我先休息一会,再接着尝试。打印的日志大概就说的是这个意思。
解决的方向很简单:把 yarn 的信息配上不就行吗?
关键是怎么配呀,api 是什么呀,找个 demo 看看呀…emo…emo…
他也遇到了同样的问题,当他把 core-site.xml
和 yarn-site.xml
文件放在 src/main/resources
目录下后,就解决了上面那个一直连不上 yarn 的问题。
也是抱着试一试心情,没想过 6 年前的 没有人投票的 答案能 work。集群的 spark 版本是 2.4.8,为什么要用这么老的,因为甲方的 spark 就是这个版本。
回过头来再看看这个位置,其实是将两个 xml 文件放在 classpath 路径下。
附上提交代码:
private void pi() {
log.info("----- start pi -----");
final String javaHome = System.getenv("JAVA_HOME");
final String hadoopConfDir = System.getenv("HADOOP_CONF_DIR");
log.info("javaHome: " + javaHome);
log.info("hadoopConfDir: " + hadoopConfDir);
log.info("mode: " + executeMode);
log.info("appResource: " + sparkJar);
log.info("mainClass: " + mainClass);
final String[] args = new String[]{
"--jar",
sparkJar,
"--class",
mainClass,
"--arg",
"10"
};
System.setProperty("SPARK_YARN_MODE", "true");
SparkConf sparkConf = new SparkConf();
sparkConf.setMaster("yarn");
sparkConf.setAppName("spark-yarn");
sparkConf.set("spark.submit.deployMode", "cluster"); // worked
ClientArguments clientArguments = new ClientArguments(args); // spark-2.0.0
Client client = new Client(clientArguments, sparkConf);
client.run();
log.info("----- finish pi -----");
}