Hadoop MapReduce,Java实现问题

5

目前我正在学习Apache Hadoop(使用Java实现MapReduce作业)。我研究了一些示例(例如WordCount示例),并成功地玩转了编写自定义MapReduce应用程序(我正在使用Cloudera Hadoop Demo VM)。我的问题涉及一些实现和运行时问题。

作业类的原型如下:

public class WordCount {

  public static class Map extends MapReduceBase implements Mapper<LongWritable, Text, Text, IntWritable> {
    public void map(LongWritable key, Text value, OutputCollector<Text, IntWritable> output, Reporter reporter) throws IOException {
    // mapping
      }
    }
  }

  public static class Reduce extends MapReduceBase implements Reducer<Text, IntWritable, Text, IntWritable> {
    public void reduce(Text key, Iterator<IntWritable> values, OutputCollector<Text, IntWritable> output, Reporter reporter) throws IOException {
      // reducing
    }
  }

  public static void main(String[] args) throws Exception {
    JobConf conf = new JobConf(WordCount.class);
    conf.setJobName("wordcount");
    // setting map and reduce classes, and various configs
    JobClient.runJob(conf);
  }
}

我有一些问题,我试图谷歌这些问题,但我必须说,Hadoop文档非常正式(像一本大的参考书),不适合初学者。

我的问题:

  • Map和Reduce类必须是Main类的静态内部类,还是它们可以在任何地方(只要从Main可见)?
  • 您是否可以使用Java SE和可用库中提供的任何内容,就像在普通的Java SE应用程序中一样?我的意思是,像JAXB、Guava、Jackson for JSON等。
  • 编写通用解决方案的最佳实践是什么?我的意思是:我们想以不同(但略微相似)的方式处理大量日志文件。日志文件的最后一个标记始终是具有某些条目的JSON映射。一个处理可能是:按(来自映射的keyA,keyB)计数和分组日志行,另一个处理可能是:按(来自映射的keyX,keyY)计数和分组日志行。(我正在考虑一种基于配置文件的解决方案,您可以向程序提供实际需要的条目,如果您需要新的分辨率,则只需提供配置并运行应用程序)。
  • 可能很重要:在WordCount示例中,Map和Reduce类是静态内部类,而main()对它们没有任何影响,只是向框架提供这些类。您可以使这些类非静态,提供一些字段和构造函数以使用一些当前值更改运行时(例如我提到的配置参数)。

也许我在不必要地深入细节。总体问题是:Hadoop MapReduce程序是否仍然是我们习惯的普通Java SE应用程序?

1个回答

6
以下是您的答案。
1. mapper和reducer类可以在包结构中的任意位置分别位于不同的Java类中,或者作为单独的jar文件存在,只要MapTask/ReduceTask的类加载器能够加载mapper/reducer类即可。你展示的例子是为Hadoop初学者快速测试而设计的。 2. 是的,您可以使用任何Java库。这些第三方jar文件应通过hadoop jar命令的-files选项或使用Hadoop API提供给MapTask/ReduceTask。点击此处获取有关将第三方库添加到Map/Reduce类路径的更多信息。 3. 是的,您可以使用以下任一方法配置并传递配置给Map/Reduce作业。 3.1 使用org.apache.hadoop.conf.Configuration对象如下在客户端程序(带有main()方法的Java类)中设置配置 Configuration conf = new Configuration(); conf.set("config1", "value1"); Job job = new Job(conf, "Whole File input");
Map/Reduce程序可以访问Configuration对象,并使用get()方法获取属性的值。如果配置设置很少,则建议使用此方法。
3.2 使用分布式缓存加载配置并使其在Map/Reduce程序中可用。点击此处了解有关分布式缓存的详细信息。这种方法更加可取。
4. main()是客户端程序,应负责配置和提交Hadoop作业。如果没有设置任何配置,则将使用默认设置。例如,Mapper类、Reducer类、输入路径、输出路径、输入格式类、Reducers数量等配置。
另请参阅此处有关作业配置的文档。
是的,Map/Reduce程序仍然是JavaSE程序,但是这些程序分布在Hadoop集群中的机器上。假设,Hadoop集群有100个节点并提交了单词计数示例。Hadoop框架为每个Map和Reduce任务创建Java进程,并在存在数据的子集机器上调用回调方法,如map()/reduce()。实际上,你的mapper/reducer代码在存在数据的机器上执行。我建议阅读《The Definitive Guide》第6章。
希望对你有所帮助。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接