文章目录
- WordCount 案例实操
- 一、案例需求
- 二、案例分析
- 三、代码实现
- 1、Map阶段代码
WordCount 案例实操
一、案例需求
1、需求:在给定的文本文件中统计输出每一个单词的总次数
2、期望输出数据
atguigu 2
banzhang 1
cls 2
hadoop 1
jiao 1
ss 2
xue 1
二、案例分析
按照MapReduce 编程规范,分别编写 Mapper,Reducer,Driver,如下图所示
Mapper 只负责切和分:
Mapper
首先传入进来是,Text
类型,但是我们对``类型的数据操作不熟悉,所以把它再转换为String
类型的进行操作,读取行数据,然后根据空格将这一行的数据进行切分,成两个单词,有空格的才切哈,没得空格就不切。然后将单词输出为<单词,1>,
Reducer 负责汇总:
Rducer
阶段拿到的数据就是,刚刚Map
阶段切分好的数据,汇总各个key
的个数,比如以 atguigu
为key
的单词,他们就会进入到同一个Reduce
方法里面去,然后会将同一个Reduce
方法里面的单词,进行汇总,就可以得到这个单词的次数
Driver
运行程序提交作业: 这是固定的程序,基本所有的程序都这么写
获取配置信息,获取job对象实例,指定本程序的jar所在的本地路经,关联Mapper/Reducer业务类,指定Mapper输出类型的KV值类型,指定最终输出的数据的KV类型,指定job的输入原始文件所在目录,指定job的输出结果所在目录,然后最后提交作业
三、代码实现
1、Map阶段代码
package com.aex.mr;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Mapper;
import java.io.IOException;
//map阶段
//KEYIN 第一个参数,输入数据的类型 行偏移量 0-19 然后第二行就是 20-25 第三行26-35 会有一点偏差
//VALAUEIN 第二个参数 输入数据的value Text 也就是String类型,因为读取进来的单词全是文本类型
//KEYOUT 输出数据的类型是KV atguigu,1 ss,1是这个样子的,所以应该设置为 Text IntWritable
//VALUEOUT 输出的数据的value类型 最后这两个是作为Reduce阶段的输入,这两个写什么Reduce的输入类型就写什么
public class WordCountMapper extends Mapper<LongWritable, Text,Text, IntWritable> { //第一个泛型是数据的类型,
Text k = new Text();
IntWritable v = new IntWritable(1);
@Override //每次key/value都会调用一次,输入的切片,必须要重写这个map方法
protected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
//LongWritable kye 和Mapper类的LongWritable对应,是行偏移量。Text value和Text对应是输入数据的类型值
//atguigu atguigu 一次只读取一行数据,第一次是第一行,就把这个atguigu读进来了
//ss ss
// 1 获取一行,他是Text类型,我们的给他转换成String类型的
String line = value.toString(); //我们吧这个value使用tostring方法转换成string类型
// 2 然后中间是有空格的,我们得根据空格进行切割单词
String[] words = line.split(" ");//直接使用split方法进行切割,中间直接是空格,
//然后切割完的结果返回一个数组,比如数组第一个就是第一个atguigu 然后数组第二个就是第二个atguigu
// 3 循环写出
for (String word:words){ //循环遍历这个数组,
//atguigu 因为这个对象要是写在循环里的话每次都要创造一个对象有点耗内存,所以写在外面当全局变量一样的,但是我不删,注释了放在这里容易看懂
//Text k = new Text(); //因为下面的context.write方法写入,然后key是Text类型的,所以new一个新的变量对象
k.set(word); //然后把这个数组放进去.atguigu atguigu
//1
//IntWritable v = new IntWritable(); //值value是IntWritable类型的,也要new 一个新的变量对象,然后把他们两个传入进去就行了
//v.set(1); //k是设置的单词。那么v就是1 然好map阶段的任务完成,数据输出变成atguigu,1 atguigu 1
context.write(k,v); //使用context.write方法写出去,两个参数key,value。以单词为key,单词的数量为value
}
}
}