本帖最后由 丫丫 于 2016-12-26 16:00 编辑
问题导航
1、localizedPath是怎么得到的呢?
2、distribute函数里面的参数,分别对应哪些内容?
3、jars参数是怎么得到的呢?
软件环境:
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里面的参数:
[mw_shl_code=text,true]
#oozie.use.system.libpath=true
oozie.libpath=${nameNode}/user/oozie/share/lib/lib_20161222004831/spark
[/mw_shl_code]
采用第二行的方式,而非第一行的方式(第二行中的lib_2016...是时间戳,每个集群应该不一样);
结果使用这种方式依然不行,还是报同样的错误;
那么看看到底是处理哪个jar包路径出问题呢?怎么做?
修改Client源码的第473行,添加一行打印:
[mw_shl_code=java,true]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
}
}
}
} [/mw_shl_code]
然后再次查看日志:
发现: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参数既然得到的有重复的,那么去重就可以了,如下:
[mw_shl_code=java,true] 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
}
}
}
} [/mw_shl_code]
编译该源码(如果自己编译记得去掉那行打印),得到其class,如下:
2. 替换Jar包
(上传、删除注意HDFS权限)
把HDFS上的oozie的sharelib下包含Client的jar包下载下来,这个jar包在我集群中的位置是(注意时间戳):
[mw_shl_code=text,true] /user/oozie/share/lib/lib_20161222004831/spark/spark-yarn_2.10-1.6.0-cdh5.7.3.jar [/mw_shl_code]
把这个jar包先下载到linux,然后下载到windows;接着删掉HDFS上的该jar包:
[mw_shl_code=text,true]hdfs dfs -rm -r /user/oozie/share/lib/lib_20161222004831/spark/spark-yarn_2.10-1.6.0-cdh5.7.3.jar[/mw_shl_code]
在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:
[mw_shl_code=text,true]hdfs dfs -put spark-yarn_2.10-1.6.0-cdh5.7.3.jar /user/oozie/share/lib/lib_20161222004831/spark/ [/mw_shl_code]
再次运行,发现Oozie任务成功运行:
总结:
1. 在使用一些多个框架技术的时候,如果找不到资料解决问题,那么最直接的方式是查看源码;
2. bug无处不在!
来源:blog.csdn
作者:fansy1990
|
|