【问题标题】:Hadoop Mapreduce multiple Input filesHadoop Mapreduce 多个输入文件
【发布时间】:2012-10-25 14:34:03
【问题描述】:

所以我需要两个文件作为我的 mapreduce 程序的输入:City.dat 和 Country.dat

在我的主要方法中,我会像这样解析命令行参数:

Path cityInputPath = new Path(args[0]);
Path countryInputPath = new Path(args[1]);
Path outputPath = new Path(args[2]);
MultipleInputs.addInputPath(job, countryInputPath, TextInputFormat.class, JoinCountryMapper.class);
MultipleInputs.addInputPath(job, cityInputPath, TextInputFormat.class, JoinCityMapper.class);
FileOutputFormat.setOutputPath(job, outputPath);

如果我现在使用以下命令运行我的程序:

hadoop jar capital.jar org.myorg.Capital /user/cloudera/capital/input/City.dat /user/cloudera/capital/input/Country.dat /user/cloudera/capital/output

我收到以下错误:

Exception in thread "main" org.apache.hadoop.mapred.FileAlreadyExistsException: Output directory /user/cloudera/capital/input/Country.dat already exists

为什么它把它当作我的输出目录?我指定了另一个目录作为输出目录。有人可以解释一下吗?

【问题讨论】:

  • 能否请您更改问题标题,因为它会使任何第一次回答问题的人感到困惑。

标签: java command-line hadoop mapreduce command-line-arguments


【解决方案1】:

根据堆栈跟踪,您的输出目录不为空。所以最简单的其实就是在运行作业之前删除它:

bin/hadoop fs -rmr /user/cloudera/capital/output

除此之外,您的参数以主类的类名org.myorg.Capital 开头。这就是第零个索引的论点。 (基于堆栈跟踪和您提供的代码)。

基本上,您需要将所有索引向右移动一个:

Path cityInputPath = new Path(args[1]);
Path countryInputPath = new Path(args[2]);
Path outputPath = new Path(args[3]);
MultipleInputs.addInputPath(job, countryInputPath, TextInputFormat.class, JoinCountryMapper.class);
MultipleInputs.addInputPath(job, cityInputPath, TextInputFormat.class, JoinCityMapper.class);
FileOutputFormat.setOutputPath(job, outputPath);

别忘了清除你的输出文件夹!

还有一个小提示,您可以用逗号“,”分隔文件,这样您就可以像这样通过一次调用来设置它们:

hadoop jar capital.jar org.myorg.Capital /user/cloudera/capital/input/City.dat,/user/cloudera/capital/input/Country.dat

在你的 java 代码中:

FileInputFormat.addInputPaths(job, args[1]);

【讨论】:

  • 这很奇怪,因为我总是用这个命令启动我的程序,它从来没有把 org.myorg.Class 作为第零个参数。奇怪地移动我的所有索引会导致相同的错误。而且我的输出文件夹也不存在。问题是它认为 /user/cloudera/input/Country.dat 是我的输出文件夹......这就是它不为空的原因。问题是为什么它认为这是我的输出文件夹。
  • 如果它导致完全相同的错误,你没有运行你提供的代码。
  • 就我所遇到的问题而言,@gaussd 是对的。 org.myorg.Capital 不是 args 中的第 0 个元素。它只是说“从 capital.jar 文件中的 org.myorg.Capital 类开始”..
【解决方案2】:

这里发生的事情是类名被认为是第一个参数!

默认情况下,第一个非选项参数是要调用的类的名称。应使用完全限定的类名。如果指定了 -jar 选项,则第一个非选项参数是包含应用程序的类和资源文件的 JAR 归档的名称,启动类由 Main-Class 清单头指示。

所以我建议你add a Manifest files to your jar 在哪里指定主类。您的 MANIFEST.MF 文件可能如下所示:

Manifest-Version: 1.0
Main-Class: org.myorg.Capital

现在你的命令看起来像:

hadoop jar capital.jar /user/cloudera/capital/input/City.dat /user/cloudera/capital/input/Country.dat /user/cloudera/capital/output

您当然可以只更改代码中使用的索引值,但这不是可取的解决方案。

【讨论】:

    【解决方案3】:

    你可以试试这个:

    hadoop jar capital.jar /user/cloudera/capital/input /user/cloudera/capital/output

    这应该读取单个输入目录中的所有文件。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-06-16
      • 1970-01-01
      • 1970-01-01
      • 2014-07-22
      相关资源
      最近更新 更多