上面的例子还不完整,统计数据没有排序,而且输出的output文件是二进制格式的。现在修改一下
Statistic.java:
public static void main(String[] args) throws IOException
{
Configuration defaults = new Configuration();
new JobClient(defaults).getFs().delete(new File("tmp/output/"));
File tempDir = new File("tmp/stat-temp-"+Integer.toString(
new Random().nextInt(Integer.MAX_VALUE)));
JobConf statJob = new JobConf(defaults, Statistic.class);
statJob.setJobName("StatTestJob");
statJob.setInputDir(new File("tmp/input/"));
statJob.setMapperClass(StatMapper.class);
statJob.setReducerClass(StatReducer.class);
statJob.setOutputDir(tempDir);
statJob.setOutputFormat(SequenceFileOutputFormat.class);
statJob.setOutputKeyClass(UTF8.class);
statJob.setOutputValueClass(LongWritable.class);
JobClient.runJob(statJob);
JobConf sortJob = new JobConf(defaults, Statistic.class);
sortJob.setInputDir(tempDir);
sortJob.setInputFormat(SequenceFileInputFormat.class);
sortJob.setInputKeyClass(UTF8.class);
sortJob.setInputValueClass(LongWritable.class);
sortJob.setMapperClass(InverseMapper.class);
sortJob.setNumReduceTasks(1); // write a single file
sortJob.setOutputDir(new File("tmp/output/"));
sortJob.setOutputKeyComparatorClass(LongWritable.DecreasingComparator.class);// sort by decreasing freq
JobClient.runJob(sortJob);
new JobClient(defaults).getFs().delete(tempDir);
}
这里将Key和Value(Action,统计值)反转,然后再重新排序后输出成单一的文本文件,以 (统计值,动作)的方式。
感觉处理过程每次都需要经历Map和Reduce的过程,“可能”会造成效率下降,但是Google的MapReduce论文上面清楚写着:
The performance of the MapReduce library is good enough that we can keep conceptually unrelated computations separate, instead of mixing them togetherto avoid extra passes over the data.
MapReduce的函数库的性能已经非常好,所以我们可以把概念上不相关的计算步骤分开处理,而不是混在一起以期减少处理次数。
这里以及说明了,尽可能让Map和Reduce每次都执行较为简单的操作,而不应该为了追求效率而将不相关的操作集中在一起执行。
Hadoop 表面上的东西简单说了一下,如果要深入研究运行机制,以及如何再多台机器上面执行分布式计算,这就需要对源码进行研究了。