文章目录
1、MapReduce定义
一个分布式运算程序的编程框架
1.1 分布式
指多台服务器共同完成计算
1.2 编程框架
- 如果没有框架
很多底层,服务器之间的交互代码都得自己完成 - 有框架
用户只关心自己的业务逻辑代码
核心功能是将用户编写的业务逻辑代码和自带默认组件整合成一个完整的分布式运算程序
2、MapReduce优缺点
2.1 优点
-
易于编程
用户只关心自己的业务逻辑代码,实现框架接口 -
良好的扩展性
可以动态增加服务器,解决计算资源不够的问题 -
高容错性
任何一台服务器挂掉,可以将任务转移到其他节点 -
适合海量数据的计算
TB、PB,可以实现几千台服务器并发共同计算
2.2 缺点
-
不擅长实时计算
无法像MySQL一样,在毫秒或者秒级内返回结果
一般的任务都是 分钟/小时/最长7天 级别 -
不擅长流式计算
MapReduce的输入数据集是静态的,不能动态变化
SparkStreaming、Flink擅长 -
不擅长DAG(有向无环图)计算
多个应用程序存在依赖关系,后一个应用程序的输入为前一个的输出
在这种情况下,MapReduce并不是不能做,而是使用后,每个MapReduce作业的输出结果都会写入到磁盘,会造成大量的磁盘IO,导致性能非常的低下。
Spark擅长
3、MapReduce核心思想
分布式的运算程序往往需要分成至少2个阶段
3.1 两个阶段
3.1.1 MapTask:对任务切分
例如:
1.将 1280M 的文件切分成10份
- 一个MapTask默认处理一个文件块大小的数据
2.10份文件并行计算,互不影响
- 按行读取数据
3.1.2 ReduceTask:对任务合并
依赖于MapReduce输出的 KV 数据进行输出
3.2 例子:
3.2.1 MapTask:对任务切分
任务:统计 a-p字母 和 q-z字母 出现次数
- 按行读取数据
- 根据空格切分行内单词
- 生成KV键值对( 单词 , 1)
- 根据任务分区(分区1:a-p 分区2:q-z),生成两个溢写文件
3.2.2 ReduceTask:对任务合并
- Reduce1:统计a-p字母出现次数;Reduce2:统计q-z字母出现次数
4、MapReduce进程
4.1 MrAppMaster
负责整个程序的过程调度及状态协调
- Yarn 中, Application Master 做为任务的老大,是 MrAppMaster的父类。
- 一个任务会有1个或者多个MrAppMaster (多个MrAppMaster : 串行执行,就是多个MR效率不高)
- 笼统意义上讲:一个job、一个任务、一个MR都是一回事
4.2 MapTask
负责Map阶段整个数据处理流程
JPS显示yarnchild进程
4.3 ReduceTask
负责Reduce阶段整个数据处理流程
JPS显示yarnchild进程
5、官方WordCount源码
5.1 路径
/opt/module/hadoop-3.1.3/share/hadoop/mapreduce
5.2 案例
hadoop-mapreduce-examples-3.1.3.jar
5.3 对Jar包反编译
里面有很多官方的MR案例
5.4 一个MR一般包含3个类
5.4.1 Driver驱动程序:主方法
public static void main(String[] args) throws Exception {
Configuration conf = new Configuration();
String[] otherArgs = new GenericOptionsParser(conf, args).getRemainingArgs();
if (otherArgs.length < 2) {
System.err.println("Usage: wordcount <in> [<in>...] <out>");
System.exit(2);
}
Job job = Job.getInstance(conf, "word count");
job.setJarByClass(WordCount.class);
job.setMapperClass(TokenizerMapper.class);
job.setCombinerClass(IntSumReducer.class);
job.setReducerClass(IntSumReducer.class);
job.setOutputKeyClass(Text.class);
job.setOutputValueClass(IntWritable.class);
for (int i = 0; i < otherArgs.length - 1; i++) {
FileInputFormat.addInputPath(job, new Path(otherArgs[i]));
}
FileOutputFormat.setOutputPath(job, new Path(otherArgs[(otherArgs.length - 1)]));
System.exit(job.waitForCompletion(true) ? 0 : 1);
}
5.4.2 继承Mapper类
public static class TokenizerMapper extends Mapper<Object, Text, Text, IntWritable> {
private static final IntWritable one = new IntWritable(1);
private Text word = new Text()<