通过一个例子了解MapReduce

来源:互联网 发布:c语言常用的头文件 编辑:程序博客网 时间:2024/05/22 08:13

写MapReduce程序的步骤:

  1. 把问题转化为MapReduce模型;
  2. 设置运行参数;
  3. 写map类;
  4. 写reduce类;

例子:统计单词个数

Map的任务是将内容用“ ”分开,然后每个都对应1,Reduce将相同的统计起来

1,Map端:一行行读文件,程序转化为中间Key/Value。每一个键值对调用一次map函数。

hello you hello me → hello 1,you 1,hello 1,me 1;

2,Reduce端:相同的Key肯定会在一起。经过Reduce方法处理后形成最终的Key/Value

hello 1,hello 1→hello 2;



写一个MapClass extends Mapper<keyin,valuein,keyout,valueout>类,实现map方法;

用java思想理解:

[java] view plaincopyprint?在CODE上查看代码片派生到我的代码片
  1. //word.txt 内容(两行)  
  2. //"hello you hello world    →hello 1, you 1,hello 1,world 1  
  3. //hello me";                →hello 1,me 1     
  4.   
  5. String str = "hello you hello world";  
  6. //String[] strs=str.split(" ");//按空格划分  
  7. //strs[0]=hello →map(key,1) →map(hello,1)  

用MapReduce实现:

[java] view plaincopyprint?在CODE上查看代码片派生到我的代码片
  1. package mapreduce;  
  2.   
  3. import java.util.StringTokenizer;  
  4.   
  5. import org.apache.hadoop.io.IntWritable;  
  6. import org.apache.hadoop.io.Text;  
  7. import org.apache.hadoop.mapreduce.Mapper;  
  8.   
  9. public class MapClass extends Mapper<Object, Text, Text, IntWritable> {  
  10.     //Mapper<KEYIN, VALUEIN, KEYOUT, VALUEOUT>  
  11.     //参数:Object,Text(和java的String一样),Text,IntWritable(和java int一样)  
  12.     //Map的输出是Reduce的输入;  
  13.       
  14.     public Text keyText = new Text("key");//相当于String ketText="key"  
  15.     public IntWritable intValue = new IntWritable(1);  
  16.     protected void map(Object key, Text value, Context context) throws java.io.IOException, InterruptedException {  
  17.         //获取值  
  18.         String str = value.toString();  
  19.         //默认空格分割  
  20.         StringTokenizer stringToKenizer = new StringTokenizer(str);  
  21.   
  22.         while (stringToKenizer.hasMoreTokens()) {  
  23.             keyText.set(stringToKenizer.nextToken());  
  24.             context.write(keyText, intValue);//context.write("My",1) //上下文  
  25.         }  
  26.     };  
  27.   
  28. }  


一个ReduceClass  extends Reducer< keyin,valuein,keyout,valueout >类;实现reduce方法:

[java] view plaincopyprint?在CODE上查看代码片派生到我的代码片
  1. package mapreduce;  
  2.   
  3. import org.apache.hadoop.io.IntWritable;  
  4. import org.apache.hadoop.io.Text;  
  5. import org.apache.hadoop.io.VLongWritable;  
  6. import org.apache.hadoop.mapreduce.Reducer;  
  7.   
  8. public class ReduceClass extends Reducer<Text, IntWritable, Text, IntWritable> {  
  9.     //Reducer<KEYIN, VALUEIN, KEYOUT, VALUEOUT>   
  10.     //Map的输出是Reduce的输入;  
  11.   
  12.     public IntWritable intValue = new IntWritable(1);  
  13.   
  14.     protected void reduce(Text key, java.lang.Iterable<IntWritable> values,//name [1,1]  
  15.             org.apache.hadoop.mapreduce.Reducer<Text, IntWritable, Text, IntWritable>.Context context) throws java.io.IOException, InterruptedException {  
  16.         int sum = 0;  
  17.         while (values.iterator().hasNext()) {  
  18.             sum += values.iterator().next().get();  
  19.         }  
  20.         intValue.set(sum);  
  21.         context.write(key, intValue);//上下文  
  22.   
  23.     };  
  24.   
  25. }  

接下来写main测试,新建一个类WordCounter(其中的main拷贝源码例子中的main如下:

hadoop-1.1.2\src\examples\org\apache\hadoop\examples\WordCount.java

[java] view plaincopyprint?在CODE上查看代码片派生到我的代码片
  1. public static void main(String[] args) throws Exception {  
  2.     Configuration conf = new Configuration();  
  3.     String[] otherArgs = new GenericOptionsParser(conf, args).getRemainingArgs();  
  4.     if (otherArgs.length != 2) {  
  5.       System.err.println("Usage: wordcount <in> <out>");  
  6.       System.exit(2);  
  7.     }  
  8.     Job job = new Job(conf, "word count");  
  9.     job.setJarByClass(WordCount.class);  
  10.     job.setMapperClass(TokenizerMapper.class);  
  11.     job.setCombinerClass(IntSumReducer.class);  
  12.     job.setReducerClass(IntSumReducer.class);  
  13.     job.setOutputKeyClass(Text.class);  
  14.     job.setOutputValueClass(IntWritable.class);  
  15.     FileInputFormat.addInputPath(job, new Path(otherArgs[0]));  
  16.     FileOutputFormat.setOutputPath(job, new Path(otherArgs[1]));  
  17.     System.exit(job.waitForCompletion(true) ? 0 : 1);  
  18.   }  

WordCounter类

[java] view plaincopyprint?在CODE上查看代码片派生到我的代码片
  1. package mapreduce;  
  2.   
  3. import java.io.IOException;  
  4.   
  5. import org.apache.hadoop.conf.Configuration;  
  6. import org.apache.hadoop.fs.Path;  
  7. import org.apache.hadoop.io.IntWritable;  
  8. import org.apache.hadoop.io.Text;  
  9. import org.apache.hadoop.mapreduce.Job;  
  10. import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;  
  11. import org.apache.hadoop.mapreduce.lib.input.TextInputFormat;  
  12. import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;  
  13. import org.apache.hadoop.mapreduce.lib.partition.HashPartitioner;  
  14. import org.apache.hadoop.util.GenericOptionsParser;  
  15.   
  16. public class WordCounter {  
  17.     public static void main(String[] args) throws IOException, InterruptedException, ClassNotFoundException {  
  18.         Configuration conf = new Configuration();  
  19.         String[] otherArgs = new GenericOptionsParser(conf, args).getRemainingArgs();  
  20.         if (otherArgs.length != 2) {  
  21.             System.err.println("Usage: wordcount <in> <out>");  
  22.             System.exit(2);  
  23.         }  
  24.         Job job = new Job(conf, "word count");  
  25.         job.setJarByClass(WordCounter.class);//打包jar要写,执行的类:本类  
  26.         job.setMapperClass(MapClass.class);//MapClass类  
  27.         //job.setCombinerClass(IntSumReducer.class);  
  28.         job.setReducerClass(ReduceClass.class);//ReduceClass类  
  29.         job.setOutputKeyClass(Text.class);//输出的key类型  
  30.         job.setOutputValueClass(IntWritable.class);//输出的value类型  
  31.         FileInputFormat.addInputPath(job, new Path(otherArgs[0]));//输入参数  
  32.         FileOutputFormat.setOutputPath(job, new Path(otherArgs[1]));//输出参数  
  33.         System.exit(job.waitForCompletion(true) ? 0 : 1);  
  34.   
  35.     }  
  36. }  


完成后导出成jar包放到hadoop运行:

右击包名,Export,Java,JAR file 导出,拷贝到Linux桌面;

上传到hadoop: 记得打开java进程:start-all.sh

[html] view plaincopyprint?在CODE上查看代码片派生到我的代码片
  1. [root@hadoop Desktop]# hadoop fs -put mapreduceTest.jar /  
新建一个文件:
[html] view plaincopyprint?在CODE上查看代码片派生到我的代码片
  1. root@hadoop Desktop]# vi wordTest.txt  
内容:
[html] view plaincopyprint?在CODE上查看代码片派生到我的代码片
  1. hello you   
  2. hello me   
  3. hello world  
将文件上传到hadoop:

[html] view plaincopyprint?在CODE上查看代码片派生到我的代码片
  1. [root@hadoop Desktop]# hadoop fs -put wordTest.txt /  
运行:参数4:包名加类名;5上一步上传到的文件,6输出到哪里
[html] view plaincopyprint?在CODE上查看代码片派生到我的代码片
  1. [root@hadoop Desktop]# hadoop jar mapreduceTest.jar cn.mapreduce.WordCounter /wordTest.txt /outputTest  
查看日志:(/part-r-00000是固定的)
[html] view plaincopyprint?在CODE上查看代码片派生到我的代码片
  1. [root@hadoop Desktop]# hadoop fs -text /outputTest/part-r-00000  
  2. Warning: $HADOOP_HOME is deprecated.  
  3.   
  4. hello   3  
  5. me  1  
  6. world   1  
  7. you 1  

完成;
0 0
原创粉丝点击