我目前正在使用maven进行依赖关系管理。
在这种情况下,我编写了一个方法,将map-reduce作业提交给hadoop,然后为此方法编写了一个junit测试。
当我运行mvn package
它成功编译(所有依赖关系都正确)时,单元测试失败了。
在工作跟踪器上我可以看到ClassNotFoundException
表示我的地图,组合&在节点上找不到reduce类。
我不想使用conf.setJar
手动设置此jar文件的路径。
有没有办法让它自动运行?
答案 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);
}