1

我编写了一个简单的 MapReduce 代码,它将调用外部 jar 中的几个方法。我在 hadoop/lib 文件夹中添加了这个 jar,它正在被拾取。单节点集群一切正常。我有一个多节点集群,我想在其中运行相同的代码。我想知道是否有一种方法可以将我的 jar 复制到 dfs,这样我就不需要在所有节点上手动添加 jar。我想在另一个文件夹(不是 hadoop/lib)中添加所有 jar。有可能实现这一目标吗?即添加对具有许多罐子的文件夹的外部引用。我跟着 cloudera 博客做了同样的事情,但它仍然没有帮助。对此的任何指示都会非常有帮助。我正在使用 hadoop 1.0.4 版本。

PS:我已经在主作业 jar 中添加了所有外部 jar。即使那样,它也没有被捡起。

4

1 回答 1

2

有两种机制可以将其他 jar 包含到您的作业的类路径中:

如果您尚未将它们存储在 HDFS 中,则可以使用 GenericOptionsParser 的-libjars参数。这将导致 JobClient 为您的作业将 jars 上传到 HDFS 中的临时目录,并将它们包含在您的作业的分布式缓存中。为此,您需要通过 ToolRunner.run 界面运行您的作业:

public class MyJob extends COnfigured implements Tool {
  public int run(String args[]) {
    Job job = new Job(getConf());
    // configure your job
    // ..

    return job.waitForCompletion() ? 0 : 1;
  }

  public static void main(String args[]) throws Exception {
    ToolRunner.run(new MyJob(), args));
  }
}

然后您将按如下方式运行您的作业(将 jars 1-3 添加到作业类路径):

#> hadoop jar myjob.jar MyJob -libjars jar1.jar,jar2.jar,jar3.jar [other args]

如果您的 jars 已经在 HDFS 中,那么您只需将 jars 添加到分布式缓存中:

public int run(String args[]) {
  Job job = new Job(getConf());
  // configure your job
  // ..

  // acquire job configuration
  Configuration conf = job.getConf();

  // create a FileSystem
  FileSystem fs = FileSystem.get(fs);

  DistributedCache.addFileToClassPath(new Path("/myapp/jar1.jar"), conf, fs);
  DistributedCache.addFileToClassPath(new Path("/myapp/jar2.jar"), conf, fs);
  DistributedCache.addFileToClassPath(new Path("/myapp/jar3.jar"), conf, fs);

  return job.waitForCompletion() ? 0 : 1;
}

第二种方法的唯一缺点是您不能在作业配置中引用这些 jar 中的任何类(除非您也有副本客户端,并且您配置了HADOOP_CLASSPATHenv 变量)。

于 2013-03-02T12:39:50.297 回答