如何通过jobClient自动将jar提交给hadoop

时间:2013-07-09 08:48:17

标签: java maven hadoop

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

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

当我运行mvn package它成功编译(所有依赖关系都正确)时,单元测试失败了。

在工作跟踪器上我可以看到ClassNotFoundException表示我的地图,组合&在节点上找不到reduce类。

我不想使用conf.setJar手动设置此jar文件的路径。

有没有办法让它自动运行?

1 个答案:

答案 0 :(得分:1)

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

我的建议是让你的单元测试进入集成测试 - maven生命周期的这个阶段发生在package之后,你将有一个jar,你可以通过它调用setJar并知道你将有一个jar(我猜这里你不想在普通的测试阶段调用setJar,因为jar还没有建成。)

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

作为参考,这里是一个最小的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);
}