我用Java编写了一个mapreduce程序,我可以将其提交给以分布式模式运行的远程集群。 目前,我使用以下步骤提交作业:
- 将 MAPREUCE 作业导出为 jar(例如
myMRjob.jar
) - 使用以下 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 作业集成到我的脚本中,那就太棒了!
如果你从定义作业类的 Eclipse 项目中提交 hadoop 作业,那么你很可能遇到了类路径问题。
job.setjarByClass(CountRows.class)
调用是在构建类路径上查找类文件,而不是在 CountRows 中查找类文件.jar (可能尚未构建,甚至尚未构建,甚至在类路径上)。
您应该能够通过在调用 job.setjarByClass(..)
后打印出 job.getJar()
的结果来断言这是真的,如果它没有显示 jar 文件路径,则找到构建类,而不是 jar'd 类
对我有用的是导出一个可运行的 JAR(它和 JAR 之间的区别在于第一个定义了具有 main 方法的类)并选择"将所需的库打包到 JAR"选项(选择"提取..."选项会导致重复错误,并且还必须从 jar 中提取类文件,最终,就我而言,这导致无法解决找不到类异常)。
之后,您可以按照克里斯怀特的建议设置罐子。 对于Windows,它看起来像这样:job.setJar("C:\MyJar.jar");
如果它对任何人有帮助,我做了一个关于我从创建MapReduce项目并在Windows 7(在Eclipse Luna中)的Hadoop 2.2.0中运行它所学到的知识的演讲。
以下网站使用此方法配置我的 Map/Reduce 项目以使用 Eclipse 运行该项目(不将项目导出为 JAR)配置 Eclipse 以运行 Hadoop Map/Reduce 项目
注意:如果您决定调试程序,则Mapper
类和Reducer
类将无法调试。
希望对您有所帮助。 :)