分享

Spark on YARN失败是如何分析问题及解决的

丫丫 发表于 2016-12-26 15:10:30 [显示全部楼层] 只看大图 回帖奖励 阅读模式 关闭右栏 0 13446
本帖最后由 丫丫 于 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.png


解决思路:


1. 首先就是各种网上找

不过并没有找到相关的信息,找到一些,不过和我出现的问题有点不一样(有个论坛上好像说是bug);

2. 查看源码

准备环境,查看其源码,看是哪个地方报的Requirement failed,在上图中红色框里面就是对应的内容,其源代码如下所示:

1.png


而require函数如下:


1.png

这里面就会有提示 requirement failed

那么也就是说在473行中的localizedPath等于null,这样子,那么473行的require函数验证就不会通过,就会报这个异常了;localizedPath是怎么得到的呢?

这个是通过distribute函数得到,distribute函数里面的参数file其实是用户提交的参数addJars、files、archives这三个参数,分别对应哪些内容呢?(以下是YARN任务日志截图):


1.png


从上面的提交参数来看,由于files和archives都是null,那么就肯定不是这两个参数的问题,那jars这个参数是怎么得到的呢?这个参数是oozie的sharelib里面的jar,但是这个参数值往后一直找发现其结果很多,而且还有以file开头的,也就是说也会有本地的jar包;如下:

1.png

那么肯定就是这里的问题了!
初步猜测,可能是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.png


发现:1. 提示的行数变为474了,说明源码修改成功;2 . 在提示中发现到file:/opt/cloudera/parcels/CDH/lib/hadoop-mapreduce/jets3t-0.9.0.jar
提示完毕,但是这个文件并不是最后一个addJars参数文件,其后还有很多文件,如下:

1.png


为什么会是这个文件结束呢?
查找这个文件出现的次数:


1.png

会发现这个文件出现了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,如下:


1.png


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

1.png


然后把该替换后的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.png



总结:

1. 在使用一些多个框架技术的时候,如果找不到资料解决问题,那么最直接的方式是查看源码;
2. bug无处不在!


来源:blog.csdn
作者:fansy1990




没找到任何评论,期待你打破沉寂

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关闭

推荐上一条 /2 下一条