初学耗时:1h
注:CSDN手机端暂不支持章节内链跳转,但外链可用,更好体验还请上电脑端。
一、MapReduce编程规范及示例编写
1.1 编程规范。
1.2 WordCount示例编写。
记忆词:
Client、Mapper、Reducer
一、MapReduce编程规范及示例编写
1.1 ~ 编程规范。
- 用户编写的程序分成三个部分:Mapper,Reducer,Driver(提交运行 mr 程序的客户端)。
- Mapper 的输入数据是 KV 对的形式(KV 的类型可自定义)。
- Mapper 的输出数据是 KV 对的形式(KV 的类型可自定义)。
- Mapper 中的业务逻辑写在 map()方法中。
- map()方法(maptask 进程)对每一个<K,V>调用一次。
- Reducer 的输入数据类型对应 Mapper 的输出数据类型,也是 KV。
- Reducer 的业务逻辑写在 reduce()方法中。
- Reducetask 进程对每一组相同 k 的<k,v>组调用一次 reduce()方法。
- 用户自定义的 Mapper 和 Reducer 都要继承各自的父类。
- 整个程序需要一个 Drvier 来进行提交,提交的是一个描述了各种必要信息的 job 对象。
1.2 ~ WordCount示例编写。
1.2.1 . 需求。
- 在一堆给定的文本文件中统计输出每一个单词出现的总次数。
1.2.2 . 创建Maven工程:example_mr,com.hadoop.mr。
1.2.3 . 创建包名:com.hadoop.mapreduce.wordcount。
1.2.4 . 创建类:WordCountMapper。
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Mapper;
import java.io.IOException;
/**
* Created by Allen Woon
* todo 该类就是mr程序map阶段调用的类 也就是maptask运行的类
*
* KEYIN:表示map阶段输入数据kv中key类型 在默认机制下 是每行的起始偏移量 long
* VALUEIN: 表示map阶段输入数据kv中value类型 在默认机制下 是每行的内容 String
*
* KEYOUT:表示map阶段输出数据kv中key类型 在本业务中输出的是单词 String
* VALUEOUT:表示map阶段输出数据kv中value类型 在本业务中输出的是单词的次数1 long
*
* todo:mapreduce默认读取数据机制 TextInputFormat 默认读数据类 一行一行读取数据
* todo k:是每行起始的偏移量位置 v就是这一行的内容
*
* todo : Long String 是java数据类型 hadoop认为其在序列化的时候 效率低 极其垃圾
* 因此自己封装了一套数据类型 并且开发了自己的序列化机制 Writable
* long------->longWritable
* String----->Text
* int-------->IntWritable
* null------->nullWritable
*/
public class WordCountMapper extends Mapper<LongWritable, Text, Text, LongWritable> {
/**
* todo map方法就是map阶段具体业务逻辑实现的地方
* 该方法的调用和读取数据的机制有关 todo 读取一行数据调用一次map方法
*/
@Override
protected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
//把输入的一行数据转为String
String line = value.toString();// hello hive hadoop
//按照分隔符进行切割 空格
String[] words = line.split(" ");//[hello,hive,hadoop]
//遍历数组
for (String word : words) {
//把遍历出的每个单词 标记1 发送出去
context.write(new Text(word),new LongWritable(1));//<hello,1><hive,1><hadoop,1>
}
}
}
1.2.5 . 创建类:WordCountReducer。
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Reducer;
import java.io.IOException;
/**
* Created by Allen Woon
* todo 该类就是mr程序reduce阶段调用的类 也就是reducetask运行的类
* KEYIN:表示reduce阶段输入数据kv中key类型 也就是map输出的k类型 在本需求中 是单词 Text
* VALUEIN:表示reduce阶段输入数据kv中value类型 也就是map输出的v类型 在本需求中 是单词的次数1 LongWritable
*
* KEYOUT:表示reduce阶段输出数据kv中key类型 在本需求中 还是单词 Text
* VALUEOUT:表示reduce阶段输出数据kv中value类型 在本需求中 是单词的总次数 LongWritable
*/
public class WordCountReducer extends Reducer<Text,LongWritable,Text,LongWritable> {
/**
* todo reduce方法就是reduce阶段具体业务逻辑实现的地方
* 原始数据: <hadoop,1><allen,1><hadoop,1><hadoop,1><allen,1>
* todo: 排序:根据key的字典序进行排序 a---z 0---9
* <allen,1><allen,1><hadoop,1><hadoop,1><hadoop,1>
* todo: 分组:key相同的分为一组
* <allen,1><allen,1>
* <hadoop,1><hadoop,1><hadoop,1>
* todo: 在每组内 组合变成一个新的kv对: k是原来共同的k v是原来所有v组成的一个数据结构 迭代器 Iterable
* <allen,1><allen,1>------> <allen,[1,1]>
* <hadoop,1><hadoop,1><hadoop,1>----> <hadoop,[1,1,1]>
* e.g: <hive,1>--------> <hive,[1]>
*
* todo :一组一组去调用reduce方法
*/
@Override
protected void reduce(Text key, Iterable<LongWritable> values, Context context) throws IOException, InterruptedException {
//定义个变量
long count =0;
//遍历改组的values
for (LongWritable value : values) {
count +=value.get();
}
//输出该组的结果
context.write(key,new LongWritable(count));//[allen,2]
}
}
1.2.6 . 创建主类:WordCountClient,用来描述 job 并提交 job。
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;
/**
* Created by Allen Woon
* todo 该类是mr程序 运行的主类 也就是客户端所在的类通常用于程序相关属性的指定 并且负责程序提交
*/
public class WordCountClient {
public static void main(String[] args) throws Exception {
//配置参数类
Configuration conf = new Configuration();
//获的job的实例对象
Job job = Job.getInstance(conf);
//指定mr程序运行的主类
job.setJarByClass(WordCountClient.class);
//指定mr程序运行的mapper reducer类
job.setMapperClass(WordCountMapper.class);
job.setReducerClass(WordCountReducer.class);
//指定map阶段输出的kv类型
job.setMapOutputKeyClass(Text.class);
job.setMapOutputValueClass(LongWritable.class);
//指定reduce阶段输出的kv类型 也就是最终的输出类型
job.setOutputKeyClass(Text.class);
job.setOutputValueClass(LongWritable.class);
//指定输入输出的数据路径
FileInputFormat.addInputPath(job,new Path("/wordcount/input"));
FileOutputFormat.setOutputPath(job,new Path("/wordcount/output1"));
//提交job
// job.submit();
boolean result = job.waitForCompletion(true);
//退出程序
System.exit(result ? 0 :1);
}
}
- - - - - - - - - - - - - - - - - - - - - - - - - - - -
^ 至此,MapReduce编程规范及示例编写完成。
- - - - - - - - - - - - - - - - - - - - - - - - - - - -
※ 世间诱惑何其多,坚定始终不动摇。
10个相同的糖果,分给三个人,每个人至少要得一个。有( )种不同分法?
…
A、33
B、34
C、35
D、36
…
D
- - - - - - - - - - - - - - - - - - - - - - - - - - - -
注:CSDN手机端暂不支持章节内链跳转,但外链可用,更好体验还请上电脑端。
我知道我的不足,我也知道你的挑剔,但我就是我,不一样的烟火,谢谢你的指指点点,造就了我的点点滴滴:)!