1

我目前正在使用 maven 进行依赖项管理。

在这种情况下,我编写了一个将 map-reduce 作业提交给 hadoop 的方法,然后为此方法编写了一个 junit 测试。

当我跑步时mvn package它编译成功(所有依赖项都是正确的)它是失败的单元测试。

在工作跟踪器上,我可以看到ClassNotFoundException表明我的地图、组合和减少类在节点上找不到。

我不想用conf.setJar用来手动设置这个 jar 文件的路径。

有什么办法可以让它自动工作吗?

4

1 回答 1

1

您需要一种机制,您的用户代码(映射器、组合器、reducer 类等)可以通过该机制提供给 TaskTracker。这通常通过将您的类捆绑到一个 jar 文件中然后使用setJar/setJarByClass方法来处理。在后台,hadoop 会将这个 jar 上传到 HDFS 中的一个 tmp 作业目录,并将 tmp HDFS 作业 jar 添加到分布式缓存中。

我的建议是将你的单元测试变成集成测试——maven 生命周期中的这个阶段发生在打包之后,你将拥有一个 jar,然后你可以调用 setJar 并知道你将构建一个 jar(我是在这里猜测您不想在普通测试阶段调用 setJar ,因为该 jar 尚未构建)。

最后,如果您想测试您的映射器/reducer 代码而不在真正的集群中运行,您应该查看MRUnit或在 hadoop 本地模式下运行作业 - 这两种方法都不需要您构建一个 jar。

作为参考,这是一个在本地模式下运行的最小 JUnit 片段,可在我的 Ubuntu 桌面上运行(如果您的桌面是 Windows,则需要安装 cygwin 或 unxutils)。它不是单元测试,因为它没有断言输出:

@Test
public void testLocalRun() throws IOException, InterruptedException, ClassNotFoundException {
    Job job = new Job();
    job.setInputFormatClass(TextInputFormat.class);
    FileInputFormat.setInputPaths(job,
            "src/test/java/csw/hadoop/sandbox/LocalHadoopTest.java");
    job.setOutputFormatClass(TextOutputFormat.class);
    TextOutputFormat.setOutputPath(job, new Path(
            "target/hadoop-local-output"));

    job.setNumReduceTasks(0);

    job.waitForCompletion(true);
}
于 2013-07-09T10:25:26.843 回答