我编写了一个简单的MapReduce代码,它将在外部jar中调用几个方法。我在hadoop / lib文件夹中添加了这个jar,它正被拾取。单节点集群一切正常。我有一个多节点集群,我想运行相同的代码。我想知道是否有一种方法可以将我的罐子复制到dfs,这样我就不需要在所有节点上手动添加罐子了。我想在另一个文件夹(不是hadoop / lib)中添加所有jar。是否有可能实现这一目标?即将外部引用添加到具有多个jar的文件夹中。我跟着cloudera博客做了同样的事情,但仍然没有帮助。任何关于此的指针都会非常有用。我使用的是hadoop 1.0.4版本。
P.S:我在主要工作罐中添加了所有外部罐子。即使这样,它也没有被接收。
答案 0 :(得分:2)
有两种机制可以将其他jar包含在作业的类路径中:
如果尚未将它们存储在HDFS中,则可以使用GenericOptionsParser的-libjars
参数。这将导致JobClient将jar文件上传到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));
}
}
然后你按照以下方式运行你的工作(将jar 1-3添加到作业类路径):
#> hadoop jar myjob.jar MyJob -libjars jar1.jar,jar2.jar,jar3.jar [other args]
如果您的Jars已经在HDFS中,那么您只需要在分布式缓存中添加jar:
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_CLASSPATH
env变量)。