【hadoop】MapReduce简单案例:WordCount
文章主要是介绍hadoop的mapreduce的一个小案例,主要是统计数据文本word.txt中每个单词出现的次数。
1、启动hadoop的dfs、yarn;
2、上传word.txt文件到hadoop的dfs中,可以使用命令或者用javaAPI上传
命令上传 ,在当前文件目录下输入 : hadoop fs -put word.txt /word.txt;

word.txt内容随意,博主的是:

3、打开eclipse,新建一个java项目,导入相关jar包(在hadoop下的的share目录中)
主要有这三个类:
1)WCMapper.java
package com.lxq.mapreduce; import org.apache.hadoop.io.LongWritable; import org.apache.hadoop.io.Text; import org.apache.hadoop.mapreduce.Mapper; import java.io.IOException; /** * Created by Administrator on 2015/6/14. */ public class WCMapper extends Mapper<LongWritable,Text,Text,LongWritable>{ @Override protected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException { //读取数据 String line = value.toString(); //切分数据 String[] words = line.split(" "); //遍历 for (String word : words) { //每个单词作为key,记录1 context.write(new Text(word),new LongWritable(1)); } } }
2)WCReducer
package com.lxq.mapreduce; import org.apache.hadoop.io.LongWritable; import org.apache.hadoop.io.Text; import org.apache.hadoop.mapreduce.Reducer; import java.io.IOException; /** * Created by Administrator on 2015/6/14. */ public class WCReducer extends Reducer<Text,LongWritable,Text,LongWritable> { @Override protected void reduce(Text key, Iterable<LongWritable> values, Context context) throws IOException, InterruptedException { //接受数据 //统计 long counter = 0; for (LongWritable value : values) { counter += value.get(); } //输出 context.write(key,new LongWritable(counter)); } }
3)WordCount
package com.lxq.mapreduce; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.fs.Path; import org.apache.hadoop.io.LongWritable; 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; import java.io.IOException; /** * Created by Administrator on 2015/6/14. */ public class WordCount { public static void main(String[] args) throws IOException, ClassNotFoundException, InterruptedException { //构建Job对象 Job job = Job.getInstance(new Configuration()); //设置main方法所在的类 job.setJarByClass(WordCount.class); //设置Mapper相关属性 job.setMapperClass(WCMapper.class); job.setMapOutputKeyClass(Text.class); job.setMapOutputValueClass(LongWritable.class); //设置读取源文件的路径,这里应该是hdfs的文件路径 FileInputFormat.setInputPaths(job,new Path("/word.txt")); //设置Reducer相关属性 job.setReducerClass(WCReducer.class); job.setOutputKeyClass(Text.class); job.setOutputValueClass(LongWritable.class); //设置计算结果的输出路径 FileOutputFormat.setOutputPath(job,new Path("/wcout")); //提交任务 true 打印进度 false 不打印 job.waitForCompletion(true); } }
4.右键项目点击export,打包成jar

注:选择jar的入口

5.执行MapReduce
1)使用hadoop命令 执行刚才打包的jar。

2)可以看到类似于这样的一些输出信息:

3)执行完后,可以在hadoop 的 dfs根目录下看到输出结果目录

4)统计结果如下:

可以看到是 SUCCES ,代表成功了。点击下面的 part-r-xxxxx可以查看运算结果;

分别计算出了每个单词出现的次数。
6、MapReduce解释:
Mapper解析:
① 读取文件输入内容后,解析成key-value对,对于输入文件的每一行,解析成key-value对,每一个键值对调用一次map函数,读入的键值对大概是这样的:
<“偏移量”,“当前行”> ...; 字符的偏移量作为key,每一行作为value;
那么在进入WCMapper 的 map 方法时的时候,接收到的数据大概是这样的:
key = "0" , value = "hello hadoop", 因为“hello hadoop” 字符长度为12(换行不算)则下一对key-value为 <"13","hello lixiongqing"> , 如此类推;
②在WCMapper的 map 方法中,根据业务需求,编写业务逻辑,处理输入的key-value,转换成新的key-value;
在Mapper的输出的新的key-value 中,把每个单词作为Key,value为1,就是每出现一次就记录一个1,便于之后的统计。
*注:在这里Mapper会对输出key、value进行分区,对于不同分区的数据,按照key进行排序,分组,相同key的value放到一个集合中。
这里的最终输出结果是:<key,{value1,value2,...}>,......
Reducer解析:
①对多个map任务的输出,按照不同的分区,通过网络copy到不同的reduce节点。
②对于map任务的输出,进行合并,排序。在reduce函数中,编写业务逻辑,对于输入的key、value进行处理,转换成新的key、value;
在案例中,map任务的输出大概是这样的:<"hello",{1,1,1,1,1,1}>,<"hadoop",{1}>,.....
那么reduce方法接收的到 key = "hello" value为{1,1,1,1...}集合的一个迭代器
输出新的key、value 大概是这样的:<"hello",5>,<"hadoop",1>.......
③把reduce的输出结果保存到文件中。
浙公网安备 33010602011771号