hive版本wordcount

来源:互联网 发布:网络购物合同纠纷审理 编辑:程序博客网 时间:2024/04/27 18:39

1. wordcount程序相当于hadoop MapReduce的一个helloworld程序吧,主要是将文件中的单词内容一行一行得读入,在map端进行拆分,拆成key-value的形式, key是具体的单词,value是数字1,map到reduce的过程会进行一次归并,将key一样的进行合并组成key-values的形式,其中key是具体的单词,values是很多个1,在reduce端将这个values循环相加就是这个单词的个数。

2. 纯的MR代码如下:

    

[java] view plain copy
 print?
  1. /** 
  2.  *  Licensed under the Apache License, Version 2.0 (the "License"); 
  3.  *  you may not use this file except in compliance with the License. 
  4.  *  You may obtain a copy of the License at 
  5.  * 
  6.  *      http://www.apache.org/licenses/LICENSE-2.0 
  7.  * 
  8.  *  Unless required by applicable law or agreed to in writing, software 
  9.  *  distributed under the License is distributed on an "AS IS" BASIS, 
  10.  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
  11.  *  See the License for the specific language governing permissions and 
  12.  *  limitations under the License. 
  13.  */  
  14.   
  15. package com.jthink.bg.hellowrold;  
  16.   
  17. import java.io.File;  
  18. import java.io.IOException;  
  19. import java.util.StringTokenizer;  
  20.   
  21. import org.apache.hadoop.conf.Configuration;  
  22. import org.apache.hadoop.fs.Path;  
  23. import org.apache.hadoop.io.IntWritable;  
  24. import org.apache.hadoop.io.Text;  
  25. import org.apache.hadoop.mapred.JobConf;  
  26. import org.apache.hadoop.mapreduce.Job;  
  27. import org.apache.hadoop.mapreduce.Mapper;  
  28. import org.apache.hadoop.mapreduce.Reducer;  
  29. import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;  
  30. import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;  
  31.   
  32. public class WordCount {  
  33.   
  34.     public static class TokenizerMapper extends Mapper<Object, Text, Text, IntWritable> {  
  35.   
  36.         private final static IntWritable one = new IntWritable(1);  
  37.         private Text word = new Text();  
  38.   
  39.         public void map(Object key, Text value, Context context) throws IOException, InterruptedException {  
  40.             StringTokenizer itr = new StringTokenizer(value.toString());  
  41.             while (itr.hasMoreTokens()) {  
  42.                 word.set(itr.nextToken());  
  43.                 context.write(word, one);  
  44.             }  
  45.         }  
  46.     }  
  47.   
  48.     public static class IntSumReducer extends Reducer<Text, IntWritable, Text, IntWritable> {  
  49.         private IntWritable result = new IntWritable();  
  50.   
  51.         public void reduce(Text key, Iterable<IntWritable> values, Context context) throws IOException,  
  52.                 InterruptedException {  
  53.             int sum = 0;  
  54.             for (IntWritable val : values) {  
  55.                 sum += val.get();  
  56.             }  
  57.             result.set(sum);  
  58.             context.write(key, result);  
  59.         }  
  60.     }  
  61.   
  62.     public static void main(String[] args) throws Exception {  
  63.         Configuration conf = new Configuration();  
  64.         Job job = new Job(conf, "word count");  
  65.   
  66. //        File jarFile = EJob.createTempJar("bin");  
  67. //        System.out.println("jarFile==" + jarFile);  
  68. //        ((JobConf) job.getConfiguration()).setJar(jarFile.toString());  
  69.   
  70.         job.setJarByClass(WordCount.class);  
  71.         job.setMapperClass(TokenizerMapper.class);  
  72.         job.setCombinerClass(IntSumReducer.class);  
  73.         job.setReducerClass(IntSumReducer.class);  
  74.         job.setOutputKeyClass(Text.class);  
  75.         job.setOutputValueClass(IntWritable.class);  
  76.         FileInputFormat.addInputPath(job, new Path("hdfs://bg01:9000/bg/wordcount/input"));  
  77.         FileOutputFormat.setOutputPath(job, new Path("hdfs://bg01:9000/bg/wordcount/output"));  
  78.         System.exit(job.waitForCompletion(true) ? 0 : 1);  
  79.     }  
  80. }  
3. 这样做需要写很多java代码,但是如果放到hive中就比较简单(关于hive是什么就不细说了),具体做法如下:

    a. 创建一个数据库,如levi

        create database levi;

    b. 建表

create external table src_data(line string) row format delimited fields terminated by '\n' stored as textfile location '/levi/wordcount/src_data';

这里假设我们的数据存放在hadoop下,路径为:/levi/wordcount/src_data,里面主要是一些单词文件,内容大概为:

hi man
what is your name
my name is levi
you
kevin

执行了上述hql就会创建一张表src_data,内容是这些文件的每行数据,每行数据存在字段line中,select * from src_data; 就可以看到这些数据

    c. 根据MapReduce的规则,我们需要进行拆分,把每行数据拆分成单词,这里需要用到一个hive的内置表生成函数(UDTF):explode(array),参数是array,其实就是行变多列:

create table words(word string);

insert into table words select explode(split(line, " ")) as word from src_data;

split是拆分函数,跟java的split功能一样,这里是按照空格拆分,所以执行完hql语句,words表里面就全部保存的单个单词

    d. 这样基本实现了,因为hql可以group by,所以最后统计语句为:

select word, count(*) from levi.words group by word;

4. 对比写MR和写hive,还是hive比较简便,对于比较复杂的统计操作可以建一些中间表,或者一些视图之类的,之后博客会持续更新hive的一些操作。

原创粉丝点击