Hadoop实例之利用MapReduce实现Wordcount单词统计 (附源代码)

Posted sakura--

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Hadoop实例之利用MapReduce实现Wordcount单词统计 (附源代码)相关的知识,希望对你有一定的参考价值。

大致思路是将hdfs上的文本作为输入,MapReduce通过InputFormat会将文本进行切片处理,并将每行的首字母相对于文本文件的首地址的偏移量作为输入键值对的key,文本内容作为输入键值对的value,经过在map函数处理,输出中间结果<word,1>的形式,并在reduce函数中完成对每个单词的词频统计。整个程序代码主要包括两部分:Mapper部分和Reducer部分。

 

Mapper代码

 

    public  static  class  doMapper  extends  Mapper<Object,  Text,  Text,  IntWritable>  
//第一个Object表示输入key的类型;第二个Text表示输入value的类型;第三个Text表示表示输出键的类型;第四个IntWritable表示输出值的类型  
        public  static  final  IntWritable  one  =  new  IntWritable(1);  
        public  static  Text  word  =  new  Text();  
        @Override  
        protected  void  map(Object  key,  Text  value,  Context  context)  
                    throws  IOException,  InterruptedException
 //抛出异常    
            StringTokenizer  tokenizer  =  new  StringTokenizer(value.toString(),  " ");  
//StringTokenizer是Java工具包中的一个类,用于将字符串进行拆分
            while(tokenizer.hasMoreTokens()) //循环每一行拆分出的所有单词
            
                 word.set(tokenizer.nextToken()); //返回当前位置到下一个分隔符之间的字符串
                  context.write(word,  one);  //将word存到容器中,记一个数  
            
        
          
      

 

map函数里有三个参数,前面两个Object key,Text value就是输入的keyvalue,第三个参数Context context是可以记录输入的keyvalue。例如context.write(word,one);此外context还会记录map运算的状态。map阶段采用Hadoop的默认的作业输入方式,把输入的valueStringTokenizer()方法截取出的单词设置为key,设置value1,然后直接输出<key,value>

 

Reducer代码

 

    public  static  class  doReducer  extends  Reducer<Text,  IntWritable,  Text,  IntWritable>  
//参数同Map一样,依次表示是输入键类型,输入值类型,输出键类型,输出值类型
        private  IntWritable  result  =  new  IntWritable();  
        @Override  
        protected  void  reduce(Text  key,  Iterable<IntWritable>  values,  Context  context)  
        throws  IOException,  InterruptedException    
        int  sum  =  0;  
        for  (IntWritable  value  :  values)    
        sum  +=  value.get();  
          
//for循环遍历,将得到的values值累加  
        result.set(sum);  
        System.out.println(sum);
        context.write(key,  result);  
          
     

 

map输出的<key,value>先要经过shuffle过程把相同key值的所有value聚集起来形成<key,values>后交给reduce端。reduce端接收到<key,values>之后,将输入的key直接复制给输出的key,for循环遍历values并求和,求和结果就是key值代表的单词出现的总次,将其设置为value,直接输出<key,value>

完整代码:

 

import  java.io.IOException;  
import  java.util.StringTokenizer;  
import  org.apache.hadoop.fs.Path;  
import  org.apache.hadoop.io.IntWritable;  
import  org.apache.hadoop.io.Text;  
import  org.apache.hadoop.mapreduce.Job;  
import  org.apache.hadoop.mapreduce.Mapper;  
import  org.apache.hadoop.mapreduce.Reducer;  
import  org.apache.hadoop.mapreduce.lib.input.FileInputFormat;  
import  org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;  
public  class  WordCount    
    public  static  void  main(String[]  args)  throws  IOException,  ClassNotFoundException,  InterruptedException    
        Job  job  =  Job.getInstance();  
        job.setJobName("WordCount");  
        job.setJarByClass(WordCount.class);  
        job.setMapperClass(doMapper.class);  
        job.setReducerClass(doReducer.class);  
        job.setOutputKeyClass(Text.class);  
        job.setOutputValueClass(IntWritable.class);  
        Path  in  =  new  Path("hdfs://192.168.68.130:9000/user/hadoop/wordcount.txt"); //需要统计的文本所在位置 
        Path  out  = new Path("hdfs://192.168.68.130:9000/user/hadoop/output3");  //注意output3不能存在
        FileInputFormat.addInputPath(job,  in);  
        FileOutputFormat.setOutputPath(job,  out);  
        System.exit(job.waitForCompletion(true) ? 0  :  1);  
      
    public  static  class  doMapper  extends  Mapper<Object,  Text,  Text,  IntWritable>  
        public  static  final  IntWritable  one  =  new  IntWritable(1);  
        public  static  Text  word  =  new  Text();  
        @Override  
        protected  void  map(Object  key,  Text  value,  Context  context)  
                    throws  IOException,  InterruptedException    
            StringTokenizer  tokenizer  =  new  StringTokenizer(value.toString(),  " ");  
            while(tokenizer.hasMoreTokens())  
                 word.set(tokenizer.nextToken());
                  context.write(word,  one);  
            
        
          
      
    public  static  class  doReducer  extends  Reducer<Text,  IntWritable,  Text,  IntWritable>  
        private  IntWritable  result  =  new  IntWritable();  
        @Override  
        protected  void  reduce(Text  key,  Iterable<IntWritable>  values,  Context  context)  
        throws  IOException,  InterruptedException    
        int  sum  =  0;  
        for  (IntWritable  value  :  values)    
        sum  +=  value.get();  
          
        result.set(sum);  
        System.out.println(sum);
        context.write(key,  result);  
          
      
  

 

以上是关于Hadoop实例之利用MapReduce实现Wordcount单词统计 (附源代码)的主要内容,如果未能解决你的问题,请参考以下文章

大数据之Hadoop(MapReduce):FileInputFormat实现类

MapReduce编程实践——WordCount运行实例(Python实现)

MapReduce编程实例

Hadoop中的MapReduce——分布式离线计算框架

如何用mapreduce分布式实现kmeans算法

008 数据处理-MapReduce实例