目前我正在学习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应用程序?