0

有几个相关的问题,但我花了一整天的时间试图弄清楚这个问题,答案在 SO 的任何地方都没有,所以我将其记录下来以供后代使用。

我有一个 Hadoop 安装(CDH 3u6 - Hadoop 0.20.2),我想在其中发送一个具有多个 Jar 依赖项的 map reduce 作业。像大多数地方推荐的那样,我想使用分布式缓存将依赖项发送到数据节点。

 Path someHdfsPlace = new Path("my/mr/libs");
 FileStatus[] jarFiles = hdfs.listStatus(classpathFilesDir);
 for (FileStatus fs : jarFiles) {
      DistributedCache.addFileToClassPath(fs.getPath(), job.getConfiguration());
 }

我在不同的 Hadoop 集群上看到了这项工作,但现在突然不行了。该文件存在于 hdfs 中,并且似乎对其上方的文件和目录具有正确的权限,但是任何 MR 代码在尝试从 lib 加载依赖项时都会失败并出现ClassNotFound错误(因此不是损坏问题,只是这些东西在类路径上不存在。)

一篇文章建议必须设置$HADOOP_CLASSPATH变量 - 这在某些情况下可能会有所帮助,但我不清楚你会将它设置为什么,在我之前的工作示例中,我不必这样做,所以看起来不太可能。

无比神秘!

4

1 回答 1

0

至少对我来说,答案在这个错误报告中:

https://issues.apache.org/jira/browse/MAPREDUCE-1581

该路径可能会以完全限定路径的形式出现:hdfs://host:2456/my/mr/libs/myJar.jar在某些环境中:,路径分隔符字符会导致一组文件hdfs//host2456/my/mr/libs/myJar.jar,这些都不会导致将正确的文件添加到类中小路。

错误报告中发布的第二个解决方案对我有用 - 像这样取消路径:

 Path someHdfsPlace = new Path("my/mr/libs");
 FileStatus[] jarFiles = hdfs.listStatus(classpathFilesDir);
 for (FileStatus fs : jarFiles) {
      Path disqualified = new Path(fs.getPath().toUri().getPath());
      DistributedCache.addFileToClassPath(disqualified, job.getConfiguration());
 }
于 2013-04-23T21:07:46.070 回答