hadoop wordcount学习总结
需求
实现对文本文件中各个单词数量的统计,文本文件的内容在hdfs文件系统的/srcdata目录下,文件名称为test.txt,文件内容如下:
wo shi yi
zhi xiao yang
mao wo e e e
e heng heng heng
输出文件夹为output文件夹。
程序
在eclipse 上新建一个java工程,导入hadoop目录下面的hadoop-2.7.3\share\hadoop目录中的java包,此目录下所有的包都加入。新建一个包,包名为app,mapreduce分为两个部分,第一个部分为map阶段,wordcount的map程序的功能为:
将输入的行文本拆分成单词输出至reduce阶段。
map阶段的类取名为WordMap,代码如下所示:
package app;
import java.io.IOException;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Mapper;
//kv:输入数据KV对中的key的数据类型
//valueIn:输入kv数据对中的value数据类型
//keyout 输出kv数据的数据类型
//value 输出kv中value的数据类型
public class WordMap extends Mapper<LongWritable,Text,Text,IntWritable>
{
protected void map(LongWritable key,Text value,Context context) throws IOException, InterruptedException
{
String str = value.toString();
//将一行文本分成单词
String[] words = str.split(" ");
//输出单词用<单词,1>
for(String word:words)
{
System.out.println("map:"+word);
context.write(new Text(word),new IntWritable(1));
}
}
}
这个Mapper类是一个泛型类型,它有四个参数类型,分别指定map函数的输入键、输入值、输出键和输出值的类型。就现在这个例子来说,输入键是一个长整数便宜,输入值是一行文本,输出键是单词,输出值是1。当map阶段执行完成之后,hadoop会将相同具有相同键值的k-v对输出到recuder中,hadoop mapreduce 的运行原理如下图所示reducer类名为:WordReduce,代码如下:
package app;
import java.io.IOException;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Reducer;
class WordReduce extends Reducer<Text,IntWritable,Text,IntWritable>
{
protected void reduce(Text key,Iterable<IntWritable> values,Context context) throws IOException, InterruptedException
{
int count =0;
for(IntWritable value:values)
{
System.out.println("reduce:"+value);
count = count + value.get();
}
//输出单词的总次数
context.write(key, new IntWritable(count));
}
}
reducer类的输入要和map类的输出类型一致,这个reducer类的作用是将相同键值的次数相加,最后再进行输出。
除了mapreduce类,还要一个job提交类,job提交类取名为WordSubmit,这个类代码如下:
package app;
import java.io.IOException;
import org.apache.hadoop.conf.Configuration;
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.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
public class WordSubmit {
public static void main(String [] args) throws IOException, ClassNotFoundException, InterruptedException
{
Configuration conf = new Configuration();
Job wJob = Job.getInstance(conf);
//指定job指定的jar包位置
wJob.setJarByClass(WordSubmit.class);
wJob.setMapperClass(WordMap.class);
wJob.setReducerClass(WordReduce.class);
//
wJob.setMapOutputKeyClass(Text.class);
wJob.setMapOutputValueClass(IntWritable.class);
wJob.setOutputKeyClass(Text.class);
wJob.setOutputValueClass(IntWritable.class);
//设置要处理文本的数据在哪里
FileInputFormat.setInputPaths(wJob, "hdfs://127.0.0.1:9000/srcdata");
//最终输出结果所存放的路径
FileOutputFormat.setOutputPath(wJob, new Path("hdfs://127.0.0.1:9000/output"));
wJob.waitForCompletion(true);
}
}
我的运行环境为centos,开发环境为eclipse,需要指定指定参数和hadoop native库,启动参数设置为Debug configurations ,启动参数设置如下图所示。两个参数配置可以查看
http://yeelor.iteye.com/blog/1991075最后是运行结果,如下所示:
e 4
heng 3
mao 1
shi 1
wo 2
xiao 1
yang 1
yi 1
zhi 1