8

我用 Java 编写了一个 mapreduce 程序,我可以将它提交到以分布式模式运行的远程集群。目前,我使用以下步骤提交作业:

  1. 将 mapreuce 作业导出为 jar(例如myMRjob.jar
  2. 使用以下 shell 命令将作业提交到远程集群:hadoop jar myMRjob.jar

当我尝试运行程序时,我想直接从 Eclipse 提交作业。我怎样才能做到这一点?

我目前正在使用 CDH3,我的 conf 的精简版是:

conf.set("hbase.zookeeper.quorum", getZookeeperServers());
conf.set("fs.default.name","hdfs://namenode/");
conf.set("mapred.job.tracker", "jobtracker:jtPort");
Job job = new Job(conf, "COUNT ROWS");
job.setJarByClass(CountRows.class);

// Set up Mapper
TableMapReduceUtil.initTableMapperJob(inputTable, scan, 
    CountRows.MyMapper.class, ImmutableBytesWritable.class,  
    ImmutableBytesWritable.class, job);  

// Set up Reducer
job.setReducerClass(CountRows.MyReducer.class);
job.setNumReduceTasks(16);

// Setup Overall Output
job.setOutputFormatClass(MultiTableOutputFormat.class);

job.submit();

当我直接从 Eclipse 运行它时,作业已启动,但 Hadoop 找不到映射器/减速器。我收到以下错误:

12/06/27 23:23:29 INFO mapred.JobClient:  map 0% reduce 0%  
12/06/27 23:23:37 INFO mapred.JobClient: Task Id :   attempt_201206152147_0645_m_000000_0, Status : FAILED  
java.lang.RuntimeException: java.lang.ClassNotFoundException:   com.mypkg.mapreduce.CountRows$MyMapper  
    at org.apache.hadoop.conf.Configuration.getClass(Configuration.java:996)  
    at org.apache.hadoop.mapreduce.JobContext.getMapperClass(JobContext.java:212)  
    at org.apache.hadoop.mapred.MapTask.runNewMapper(MapTask.java:602)  
    at org.apache.hadoop.mapred.MapTask.run(MapTask.java:323)   
    at org.apache.hadoop.mapred.Child$4.run(Child.java:270)  
    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:1127)  
    at org.apache.hadoop.mapred.Child.main(Child.java:264)  
...

有谁知道如何克服这些错误?如果我能解决这个问题,我可以将更多的 MR 作业集成到我的脚本中,这太棒了!

4

3 回答 3

8

如果您从定义作业类的 Eclipse 项目中提交 hadoop 作业,那么您很可能遇到类路径问题。

job.setjarByClass(CountRows.class)调用是在构建类路径上查找类文件,而不是在 CountRows.jar 中(可能尚未构建,也可能尚未构建,甚至在类路径上)。

您应该能够通过job.getJar()在调用之后打印出结果来断言这是真的job.setjarByClass(..),如果它没有显示 jar 文件路径,那么它找到了构建类,而不是 jar'd 类

于 2012-06-28T16:19:29.170 回答
2

对我有用的是导出一个可运行的 JAR(它和 JAR 之间的区别在于第一个定义了具有 main 方法的类)并选择“将所需的库打包到 JAR”选项(选择“提取... " 选项会导致重复错误,并且它还必须从 jar 中提取类文件,在我的情况下,这最终导致无法解决未找到类的异常)。

之后,您可以按照 Chris White 的建议设置罐子。对于 Windows,它看起来像这样:job.setJar("C:\\\MyJar.jar");

如果它对任何人有帮助,我将介绍我从创建 MapReduce 项目并在 Windows 7 的 Hadoop 2.2.0 中运行它(在 Eclipse Luna 中)中学到的东西

于 2014-10-28T08:39:58.303 回答
1

我已使用以下网站中的此方法配置我的 Map/Reduce 项目以使用 Eclipse 运行项目(不将项目导出为 JAR) 配置 Eclipse 以运行 Hadoop Map/Reduce 项目

注意:如果您决定调试您的程序,您的Mapper类和Reducer类将无法调试。

希望能帮助到你。:)

于 2012-09-18T04:57:49.937 回答