Oozie Spark on YARN requirement failed
Posted fansy1990
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Oozie Spark on YARN requirement failed相关的知识,希望对你有一定的参考价值。
软件环境:
CDH:5.7.3;Oozie:4.1.0-CDH5.7.3 ; Spark:1.6.0-cdh5.7.3-hadoop2.6.0-cdh5.7.3 ; Hadoop:hadoop2.6.0-cdh5.7.3(HDFS 采用HA方式);
问题描述:
在使用CDH5.7.3版本的时候,发起一个Oozie工作流,该工作流使用Spark On YARN的方式提交一个Spark程序,但是在Oozie中该程序运行失败,同时找到YARN监控中对应的任务,发现出现下面的错误(该Spark任务如果使用spark-submit --master yarn的方式是可以提交并正确运行的):解决思路:
1. 首先就是各种网上找
不过并没有找到相关的信息,找到一些,不过和我出现的问题有点不一样(有个论坛上好像说是bug);2. 查看源码
准备环境,查看其源码,看是哪个地方报的Requirement failed,在上图中红色框里面就是对应的内容,其源代码如下所示:而require函数如下:
这里面就会有提示 requirement failed 那么也就是说在473行中的localizedPath等于null,这样子,那么473行的require函数验证就不会通过,就会报这个异常了;localizedPath是怎么得到的呢? 这个是通过distribute函数得到,distribute函数里面的参数file其实是用户提交的参数addJars、files、archives这三个参数,分别对应哪些内容呢?(以下是YARN任务日志截图):
从上面的提交参数来看,由于files和archives都是null,那么就肯定不是这两个参数的问题,那jars这个参数是怎么得到的呢?这个参数是oozie的sharelib里面的jar,但是这个参数值往后一直找发现其结果很多,而且还有以file开头的,也就是说也会有本地的jar包;如下:
那么肯定就是这里的问题了! 初步猜测,可能是Oozie在网这个里面添加jar包的时候添加多了,所以才会有本地的jar包被添加,那么试着修改job.properties里面的参数:
#oozie.use.system.libpath=true
oozie.libpath=$nameNode/user/oozie/share/lib/lib_20161222004831/spark
采用第二行的方式,而非第一行的方式(第二行中的lib_2016...是时间戳,每个集群应该不一样);
结果使用这种方式依然不行,还是报同样的错误;
那么看看到底是处理哪个jar包路径出问题呢?怎么做?
修改Client源码的第473行,添加一行打印:
val cachedSecondaryJarLinks = ListBuffer.empty[String]
List(
(args.addJars, LocalResourceType.FILE, true),
(args.files, LocalResourceType.FILE, false),
(args.archives, LocalResourceType.ARCHIVE, false)
).foreach case (flist, resType, addToClasspath) =>
if (flist != null && !flist.isEmpty())
flist.split(',').foreach file => // add distinct operation to avoid multiple same jars
val (_, localizedPath) = distribute(file, resType = resType)
println("fansy: ---->file:"+file)
require(localizedPath != null)
if (addToClasspath)
cachedSecondaryJarLinks += localizedPath
然后再次查看日志:
发现:1. 提示的行数变为474了,说明源码修改成功;2 . 在提示中发现到file:/opt/cloudera/parcels/CDH/lib/hadoop-mapreduce/jets3t-0.9.0.jar 提示完毕,但是这个文件并不是最后一个addJars参数文件,其后还有很多文件,如下:
为什么会是这个文件结束呢? 查找这个文件出现的次数:
会发现这个文件出现了2次,查询这个文件之后的文件发现都是出现了2次,但是之前的文件只出现了一次,这也就是说: 添加的addJars参数有些路径是重复的! 重复的路径经过distribute函数,处理后,第一个参数会被添加,但是重复的其实就没有必要添加了,所以distribute返回的是localizedPath就是null,这也就是为什么验证通不过的原因所在了。
解决方案:
1. 修改源码:
源码中的addjar参数既然得到的有重复的,那么去重就可以了,如下:val cachedSecondaryJarLinks = ListBuffer.empty[String]
List(
(args.addJars, LocalResourceType.FILE, true),
(args.files, LocalResourceType.FILE, false),
(args.archives, LocalResourceType.ARCHIVE, false)
).foreach case (flist, resType, addToClasspath) =>
if (flist != null && !flist.isEmpty())
flist.split(',').distinct.foreach file => // add distinct operation to avoid multiple same jars
val (_, localizedPath) = distribute(file, resType = resType)
println("fansy: ---->file:"+file)
require(localizedPath != null)
if (addToClasspath)
cachedSecondaryJarLinks += localizedPath
编译该源码(如果自己编译记得去掉那行打印),得到其class,如下:
2. 替换Jar包
(上传、删除注意HDFS权限) 把HDFS上的oozie的sharelib下包含Client的jar包下载下来,这个jar包在我集群中的位置是(注意时间戳):/user/oozie/share/lib/lib_20161222004831/spark/spark-yarn_2.10-1.6.0-cdh5.7.3.jar
把这个jar包先下载到linux,然后下载到windows;接着删掉HDFS上的该jar包:
hdfs dfs -rm -r /user/oozie/share/lib/lib_20161222004831/spark/spark-yarn_2.10-1.6.0-cdh5.7.3.jar
在windows里面使用winRAR打开下载的spark-yarn_2.10-1.6.0-cdh5.7.3.jar包,并使用编译后的Client的所有class替换对应的class;替换完成后得到该spark jar(可以在这里下载 http://download.csdn.net/detail/fansy1990/9720059 )
然后把该替换后的jar包上传到linux,再通过linux上传到HDFS:
hdfs dfs -put spark-yarn_2.10-1.6.0-cdh5.7.3.jar /user/oozie/share/lib/lib_20161222004831/spark/
再次运行,发现Oozie任务成功运行:
总结:
1. 在使用一些多个框架技术的时候,如果找不到资料解决问题,那么最直接的方式是查看源码; 2. bug无处不在!分享,成长,快乐
转载请注明blog地址:http://blog.csdn.net/fansy1990
以上是关于Oozie Spark on YARN requirement failed的主要内容,如果未能解决你的问题,请参考以下文章