MapReduce 原理篇
MapReduce 是一个分布式运算程序的编程框架,是用户开发"基于hadoop的数据分析与应用"的核心框架:
MapReduce 核心功能是 将用户编写的业务逻辑和自带默认组件整合成一个完整的分布式运算程序,并发运行在一个hadoop集群上
MapReduce java 版本 wordcount
用户编写的程序分为三个部分:Mapper、Reducer、Driver(提交运行mr 程序的客户端)
MapPer
Mapper<LongWritable, Text, Text, IntWritable>
keyin 默认情况下,是mr框架所读到的一行文本的起始偏移量,Long 但是在hadoop中有自己的更精简的序列化结构,所以不直接用Long LongWritable
valueIn 默认情况下,是mr框架所读到的一行文本内容 String,同上 Text
keyout 是用户自定义逻辑处理完成之后输出数据中的key,在此处是单词 String 同上 Text
valueout 是用户自定义逻辑处理完成之后输出数据中的value,在此处是单词次数,Integer 同上 IntWritable
map(LongWritable key, Text value, Context context)
map
map 阶段的业务逻辑就写在自定义的map()方法中,
map task 会对每一行输入数据条用一次我们自定义的map()方法
demo:
public class WordcountMapper extends
Mapper<LongWritable, Text, Text, IntWritable{
/**
* map 阶段的业务逻辑就写在自定义的map()方法中 map task 会对每一行输入数据调用一次我们自定义的map()方法
* */
@Override
protected void map(LongWritable key, Text value, Context context)
throws IOException, InterruptedException {
// 将maptask传给我们的文件内容先转换成String
String line = value.toString();
// 根据空格将这一行切分成单词
String[] words = line.split(" ");
// 将单词输出为 <单词,1>
for (String word : words) {
// 将单词作为key,将次数1作为value,以便于后续的数据分发,可以根据单词分发,
// 以便于相同单词回到相同的的 reduce task
context.write(new Text(word), new IntWritable(1));
}
}
}
Reducer
KEYIN VALUEIN
KEYOUT VALUEOUT
/**
* KEYIN VALUEIN 对应map task 输出的KEYOUT VALUEOUT类型
* KEYOUT 是单词
* VALUEOUT 是总次数
* */
public class WordcountReducer extends
Reducer<Text, IntWritable, Text, IntWritable> {
/**
* 入参 key,是一组相同单词kv对的key
* */
@Override
protected void reduce(Text key, Iterable<IntWritable> values,
Context context) throws IOException, InterruptedException {
int count = 0;
for (IntWritable value : values) {
count += value.get();
}
context.write(key, new IntWritable(count));
}
}
Driver
相当于 yarn 集群的客户端。
需要在此封装我们的mr程序的相关运行参数,指定jar包
最后提交给yarn
/**
* 相当于一个yarn 集群的客户端 需要在此封装我们的mr程序的相关运行参数,指定jar包 最后提交yarn
* */
public class WordcountDriver {
public static void main(String[] args) throws Exception {
Configuration conf = new Configuration();
conf.set("mapreduce.framework.name", "local");
// 本地模式运行mr程序时,输入输出的数据可以在本地,也可以写在hafs上
// 即mapreduce在本地以线程跑的时候,数据可以从本地读取写入,数据也可以从hdfs文件系统读取写入
// 1.数据在hdfs hdfs://192.168.125.151:9000/wordcount/input
// conf.set("fs.defaultFS", "hdfs://192.168.128.151:9000/");
// 2.数据在本地
conf.set("fs.defaultFS", "file:///");
// 运行集群模式,就是把程序提交到yarn中去运行
// 要想运行为集群模式,以下三个参数要指定yarn上的值
// conf.set("mapreduce.framework.name", "yarn");
// conf.set("yarn.resourcemanager.hostname", "min1");
// conf.set("fs.defaultFS", "hdfs://min1:9000/");
Job job = Job.getInstance(conf);
// 指定本程序的jar包所在的本地路径
job.setJarByClass(WordcountDriver.class);
// 指定本业务job要使用的mapper/reducer 业务类
job.setMapperClass(WordcountMapper.class);
job.setReducerClass(WordcountReducer.class);
// 如果不设置inputFormat,它默认用的是TextInoutFormat.class
// job.setInputFormatClass(CombineTextInputFormat.class);
// CombineTextInputFormat.setMaxInputSplitSize(job, 4194304);
// CombineTextInputFormat.setMinInputSplitSize(job, 2097152);
// 指定mapper输出数据的kv类型 (可能会使用第三方架构,所以指定mapper的输出类型)
job.setMapOutputKeyClass(Text.class);
job.setMapOutputValueClass(IntWritable.class);
// job.setCombinerClass(WordcountReducer.class);
// 指定最终输出的数据的kv类型
job.setOutputKeyClass(Text.class);
job.setOutputValueClass(IntWritable.class);
// 指定job的输入原始文件所在目录
FileInputFormat.setInputPaths(job, new Path(args[0]));
// 指定job的输出结果所在目录
FileOutputFormat.setOutputPath(job, new Path(args[1]));
// 将job中配置的相关参数,以及job所用的java类所在的java包,提交给yarn去运行
// job.submit();
boolean res = job.waitForCompletion(true);
System.exit(res ? 0 : 1);
}
}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MqcmQJbh-1598456300203)(pic/pic4.png)]