由上篇blog可知,Mapreduce架构处理问题过程中,需要map()函数和reduce()函数即可同时再添加驱动程序进行实现,本文根据老师上课所讲,对WordCount实例进行分析整理,为学习笔记,有不对的地方欢迎指正。
1.创建Maven项目
首先通过右键new-project-Maven-Maven Project(如下图所示),之后一直执行Next,进行骨架选择,选择maven-archetype-quickstart骨架,之后并进行命名,本项目命名为hadoop01,并在src/main/java下建立package名为com.qst.test。之后在其下创建MyMapper类。
2.MyMapper类 (1)map函数功能
写map函数将1.txt文件中的每一行文本读取出来,针对每一行将单词拆分,并进行映射输出,map函数任务完成。
(2)重写map函数为让我们自定义的类中MyMapper类中可以拥有分布式并行运行map函数的能力,那么就需要继承Mapreduce框架的Mapper类,从而实现重写map函数的目的。
下面结合代码具体讲解:
package com.qst.test; 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; //MyMapper类继承Mapper类,负责重写父类中的map函数,同时添加上泛型 public class MyMapper extends Mapper{ //定义一个静态类Text引用为word private Text word = new Text(); //定义一个静态常量IntWritable并让其值为1 private IntWritable one = new IntWritable(1); @Override protected void map(LongWritable key, Text value, Mapper .Context context) throws IOException, InterruptedException { System.out.println("in map, key="+key); System.out.println("in map, value="+value.toString()); //先将Text类型转化成Java的String类型 String str = value.toString(); String[] words = str.split(" "); for(String w : words) { word.set(w); context.write(word, one); } } }
- 泛型参数含义
Mapper
| LongWritable | 文本偏移量,相当于文本行的地址 |
| Text | 读取的一行文本 |
| Text | 表示map函数输出的key的类型 |
| IntWritable | 表示map函数输出的value类型 |
- map函数主要是对1.txt文件内容进行映射处理,key是从1.txt文件中读取的每行文本偏移量地址,value是从1.txt文件中获取到的一行文本,由Mapreduce框架负责传入。
- context可存放公共数据类型,比如map函数处理之后的中间结果可保存在其中,Mapreduce框架在根据context中的数据持久化到本地磁盘。
- 由于Hadoop是流式计算,即可以做序列化处理的。序列化就是将内存中的结构化的数据进行处理,使其可以在网上传递,继而可以将其存到文件中去。那么本实例中为什么要进行序列化处理?由于集群中的三个节点要进行相互数据传输,要做RPC操作。而Java中的数据类型是不直接支持序列化的,数据没办法传,因此各种数据类型在Hadoop中表示除了数据类型还加了“Writable”。一看到Writable就要知道该数据类型是可序列化的。
- Java中的字符串是不能进行序列化的,必须使用Hadoop可序列化的字符串。
protected void map(LongWritable key, Text value, Mapper
- 即该行代码中的Text value中的Text。因此要对这里的value按照Java的方式进行处理,Text和String可以相互转换:转换为Java的字符串
String str = value.toString();
- 根据传进来的字符串通过split()方法进行切割,每个空格处切割一次,并存到字符串数组中:
String[] words = str.split(" ");
- 循环遍历字符串数组words,将其中每个单词作为key值,IntWritable类型常量one作为value值
for(String w : words) {
word.set(w);
context.write(word, one);
}
经过map函数处理形成key-value键值对,输出到Mapreduce的context中去,写入本地磁盘空间。



