当前位置: 代码迷 >> Eclipse >> Sqoop源码分析(一) Eclipse调试Sqoop各种错误解决
  详细解决方案

Sqoop源码分析(一) Eclipse调试Sqoop各种错误解决

热度:27   发布时间:2016-04-23 12:59:36.0
Sqoop源码分析(一) Eclipse调试Sqoop各种异常解决

本博客属原创文章,转载请务必注明出处:http://guoyunsky.iteye.com/blog/1187778

1.ERROR tool.ImportTool: Encountered IOException running import job: org.apache.hadoop.mapred.FileAlreadyExistsException: Output directory /tmp/datas/sqoop already exists at org.apache.hadoop.mapreduce.lib.output.FileOutputFormat.checkOutputSpecs(FileOutputFormat.java:132)
?? ?at org.apache.hadoop.mapred.JobClient$2.run(JobClient.java:872)
?? ?at org.apache.hadoop.mapred.JobClient$2.run(JobClient.java:833)
?? ?at java.security.AccessController.doPrivileged(Native Method)
?? ?at javax.security.auth.Subject.doAs(Subject.java:396)
?? ?at org.apache.hadoop.security.UserGroupInformation.doAs(UserGroupInformation.java:1115)
?? ?at org.apache.hadoop.mapred.JobClient.submitJobInternal(JobClient.java:833)
?? ?at org.apache.hadoop.mapreduce.Job.submit(Job.java:476)
?? ?at org.apache.hadoop.mapreduce.Job.waitForCompletion(Job.java:506)
?? ?at com.cloudera.sqoop.mapreduce.ImportJobBase.runJob(ImportJobBase.java:107)
?? ?at com.cloudera.sqoop.mapreduce.ImportJobBase.runImport(ImportJobBase.java:166)
?? ?at com.cloudera.sqoop.manager.SqlManager.importTable(SqlManager.java:386)
?? ?at com.cloudera.sqoop.manager.MySQLManager.importTable(MySQLManager.java:125)
?? ?at com.cloudera.sqoop.tool.ImportTool.importTable(ImportTool.java:350)
?? ?at com.cloudera.sqoop.tool.ImportTool.run(ImportTool.java:423)
?? ?at com.cloudera.sqoop.Sqoop.run(Sqoop.java:144)
?? ?at org.apache.hadoop.util.ToolRunner.run(ToolRunner.java:65)
?? ?at org.apache.hadoop.util.ToolRunner.run(ToolRunner.java:79)
?? ?at com.cloudera.sqoop.Sqoop.runSqoop(Sqoop.java:180)
?? ?at com.cloudera.sqoop.Sqoop.runTool(Sqoop.java:218)
?? ?at com.cloudera.sqoop.Sqoop.main(Sqoop.java:228)

?

???? 这是我在通过Sqoop从关系型数据库导数据到Hadoop中所触发,导入的目标文件target-dir就是/tmp/datas/sqoop,网上也有解决方案,就是说要在HDFS文件系统中通过hadoop dfs -rmr /tmp/datas/sqoop干掉/tmp/datas/sqoop即可。但发现不是这么回事.但前提是确实能删除,因为我这里是在Eclipse中运行,如果能删除就没必要往下面看了.但如果发现报一下错误,或许可以帮到你:

????? rmr: cannot remove /tmp/datas/sqoop: No such file or directory.

????? HDFS中没有这个文件?于是用以下命令查看下:hadoop fs -ls /tmp/datas,还真的是空荡荡的.怎么回事?而程序里面却报Output directory /tmp/datas/sqoop already exists.这不是矛盾吗?直接告诉我Sqoop跑的Hadoop跟hadoop fs等跑的Hadoop完全不是同一个.这个在源码中得到体现得到的FileiSystem是LocalFileSystem,同时在你的机器上也会发现已经存在/tmp/datas/sqoop这个文件,Hadoop这里用的是你本地的文件系统.因为通过Shell命令启动时,Hadoop会去读取$HADOOP_HOME/conf下的配置文件,而通过Eclipse时则是采用默认的,这里解决方法也很简单,只要将$HADOOP_HOME/conf写入classpath即可.方法是,右击sqoop源码->Properties->Java Build Path->Add External Class Folder,将你Sqoop所运行的Hadoop的conf加入即可.

?

=====================================华丽的分隔===============================

?

?

2.java.lang.RuntimeException: java.lang.ClassNotFoundException:????? com.cloudera.sqoop.mapreduce.RawKeyTextOutputFormat
??? at org.apache.hadoop.conf.Configuration.getClass(Configuration.java:996)
??? at org.apache.hadoop.mapreduce.JobContext.getOutputFormatClass(JobContext.java:248)
??? at org.apache.hadoop.mapred.Task.initialize(Task.java:486)
??? at org.apache.hadoop.mapred.MapTask.run(MapTask.java:305)
??? at org.apache.hadoop.mapred.Child$4.run(Child.java:240)
??? at java.security.AccessController.doPrivileged(Native Method)
??? at javax.security.auth.Subject.doAs(Subject.java:396)
??? at org.apache.hadoop.security.UserGroupInformation.doAs(UserGroupInformation.java:1115)
??? at org.apache.hadoop.mapred.Child.main(Child.java:234)


??????? 这是我在通过Sqoop从关系型数据库导数据到Hadoop中所触发,刚碰到这个异常时很奇怪,因为我明明是在Eclipse上跑Sqoop源码,怎么会报找不到sqoop自己的类的异常.后来调试Sqoop源码后才知道这是一个Hadoop常识,大概原理如下:

?????? Sqoop生成一个Job通过MapReduce进行并行导入.而Job所依赖的资源,如jar,配置文件,输入输出等则会复制到HDFS上使得每个运行task的节点都可以使用,从而执行任务.而通过Eclipse运行时,并不会将这些打包成jar,也就是com.cloudera.sqoop.mapreduce.RawKeyTextOutputFormat没有打包到jar中,而使得运行任务的节点没有得到这些资源,所以Hadoop触发了这个异常。虽然我自己运行的也是伪分布式,但原理一样.解决的办法很简单,只要将sqoop源码打包成一个Jar放到你的$HADOOP_HOME/lib下即可

?

? ?3.通过Eclipse运行Sqoop源码跟通过Sqoop脚本($SQOOP_HOME/bin/sqoop)产生的结果不一致

? ? ? 今天碰到一个很诡异的情况,从apache上下载了Sqoop1.4,然后通过脚本运行Sqoop,发现跟通过Eclipse运行Sqoop源码结果不一致,因为之前我对Sqoop有些改动,我添加了某些功能,但官方的Sqoop并不支持.一开始还以为官方采纳了我们这边,但源码里瞅下并不如此.Eclipse源码跑下来也发现官方Sqoop并没有收纳.但运行Sqoop脚本却发现已经收纳了.真是匪夷所思,一开始认为可能是源码原因,于是重新编译了官方Sqoop1.4,但发现还是如此.于是去看sqoop脚本才发现原因:原来Sqoop是通过Hadoop执行,我这边Hadoop执行的Sqoop在其lib下,而这个lib下的Sqoop正是我之前打包好的Sqoop,所以实际上运行的一直是我之前的Sqoop,而不是新下载的Sqoop1.4.于是干掉了$HADOOP_HOME/lib下的sqoop包,重新换成新下载的Sqoop1.4,于是就正常了.现在贴上sqoop脚本下的源码:

? ? ? ? ?source ${bin}/configure-sqoop "${bin}"

? ? ? ? ?exec ${HADOOP_HOME}/bin/hadoop com.cloudera.sqoop.Sqoop "$@"

?

?

  相关解决方案