首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 其他教程 > 互联网 >

初探地图/reduce原理

2012-08-31 
初探map/reduce原理下面的代码来自于hadoop官网,但是那个例子很繁琐,我对此作了简化运行下面代码必须在lin

初探map/reduce原理
下面的代码来自于hadoop官网,但是那个例子很繁琐,我对此作了简化

运行下面代码必须在linux系统上,并且已经成功部署安装hadoop


package com.hadoop.test3;import java.io.IOException;import java.util.*;import org.apache.hadoop.fs.Path;import org.apache.hadoop.conf.*;import org.apache.hadoop.io.*;import org.apache.hadoop.mapred.*;import org.apache.hadoop.util.*;public class WordCount {public static class Map extends MapReduceBase implements Mapper<LongWritable, Text, Text, IntWritable>{private final static IntWritable one=new IntWritable(1);private Text word=new Text();public void map(LongWritable key,Text value,OutputCollector<Text, IntWritable>output,Reporter reporter)throws IOException{String line=value.toString();StringTokenizer tokenizer=new StringTokenizer(line);while(tokenizer.hasMoreElements()){word.set(tokenizer.nextToken());output.collect(word,one);}}}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{int sum=0;while(values.hasNext()){sum+=values.next().get();}output.collect(key, new IntWritable(sum));}}public static void main(String[] args) throws Exception{JobConf conf=new JobConf(WordCount.class);conf.setJobName("wordcount");conf.setOutputKeyClass(Text.class);conf.setOutputValueClass(IntWritable.class);conf.setMapperClass(Map.class);conf.setCombinerClass(Reduce.class);conf.setReducerClass(Reduce.class);conf.setInputFormat(TextInputFormat.class);conf.setOutputFormat(TextOutputFormat.class);FileInputFormat.setInputPaths(conf, new Path("/home/root/test/input"));FileOutputFormat.setOutputPath(conf, new Path("/home/root/test/output"));JobClient.runJob(conf);}}


假设:

?/home/root/test/input - 是HDFS中的输入路径
?/home/root/test/output - 是HDFS中的输出路径

1.创建 /home/root/test/input
2.在此目录下创建三个文本文件,分别命名为:file01,file02,file03
  file01输入内容"Hello World Bye World"
  file02输入内容"Hello Hadoop Goodbye Hadoop"
  file03输入内容"hello Hadoop Goodbye hadoop"

3.运行程序

运行结果为
Bye      1Goodbye  2Hadoop   3Hello    2World    2hadoop   1hello    1

从运行结果可以看出 mapreduce是区分大小写的,而且仅仅是以空格来划分字符的

在运行程序中可能会报"org.apache.hadoop.mapred.FileAlreadyExistsException"那是因为程序会自动创建输出目录,如果此目录已存在就会报此异常,所以运行前注意先删除"/home/root/test/output"目录

下面我们来看看原理

Mapper(14-26行)中的map方法通过指定的 TextInputFormat一次处理一行。然后,它通过StringTokenizer 以空格为分隔符将一行切分为若干tokens,之后,输出< <word>, 1> 形式的键值对。

对于示例中的第一个输入,map输出是:
< Hello, 1>
< World, 1>
< Bye, 1>
< World, 1>


第二个输入,map输出是:
< Hello, 1>
< Hadoop, 1>
< Goodbye, 1>
< Hadoop, 1>

第三个输入,map输出是:
< hello, 1>
< Hadoop, 1>
< Goodbye, 1>
< hadoop, 1>

WordCount还指定了一个combiner 因此,每次map运行之后,会对输出按照key进行排序,然后把输出传递给本地的combiner(按照作业的配置与Reducer一样),进行本地聚合。

第一个map的输出是:
< Bye, 1>
< Hello, 1>
< World, 2>


第二个map的输出是:
< Goodbye, 1>
< Hadoop, 2>
< Hello, 1>

第三个map的输出是:
< Goodbye, 1>
< hadoop, 1> 
< Hadoop, 1>
< hello, 1>

Reducer中的reduce方法 仅是将每个key(本例中就是单词)出现的次数求和。

因此这个作业的输出就是:
< Bye, 1>
< Goodbye, 2>
< Hadoop, 3>
< Hello, 2>
< World, 2>
< hadoop, 1>
< hello, 1>

代码中的run方法中指定了作业的几个方面, 例如:通过命令行传递过来的输入/输出路径、key/value的类型、输入/输出的格式等等JobConf中的配置信息。随后程序调用了JobClient.runJob来提交作业并且监控它的执行。

热点排行