- MapReduce是一个分布式运算程序的编程框架,是用户开发基于Hadoop的数据分析应用的核心框架
- MapReduce的核心功能是将用户编写的业务逻辑代码和自带默认组建整合成一个完整的分布式运算程序,并发运行在一个Hadoop集群上
优点:
1.MapReduce易于编程:它简单的实现一些接口,就可以完成一个分布式程序,这个分布式程序可以分布到大量的廉价机器上运行
2.良好的扩展性:可以通过简单的增加机器来扩展计算能力
3.高容错性:某一台机器挂了,可以把该机器上的计算任务转移到另一个节点运行,不会导致这个任务运行失败
4.适合PB级以上海量数据的离线处理
缺点:
1.不擅长实时计算:无法像MySQL一样在毫秒或者秒级返回结果
2.不擅长流式计算:流式计算的输入数据是动态的,而MapReduce的输入数据集是静态的,不能动态变化
3.不擅长DAG(有向图)计算: 多个应用程序存在依赖关系,后一个应用程序的输入为前一个的输出,在这种情况下,每个MapReduce作业的输出结果都会写入到磁盘,会造成大量的磁盘IO,导致性能非常的低下
MapReduce核心编程思想:
1.MapReduce运算程序一般分为两个阶段,Map阶段和Reduce阶段
2.Map阶段的并发MapTask,完全并行运行,互补想干
3.Reduce阶段的并发ReduceTask,完全互不想干,但是他们的数据依赖于上一个阶段的所有Map Task并发实例的输出
4.MapReduce编程模型只能包含一个Map阶段和一个reduce阶段,如果用户的业务逻辑非常复杂,那就只能多个MapReduce程序串行运行
图解:
抛出问题:
1.Map Task如何工作?
2.Reduce Task如何工作?
3.Map Task如何控制分区、排序?
4.Map Task和Reduce Task之间如何衔接?
-
常用数据序列化类型
MapReduce进程:
一个完整的MapReduce程序在分布式运行时有三类实例进程:
1>Mr AppMaster: 负责整个程序的过程调度及状态协调
2>MapTask:负责Map阶段的整个数据处理流程
3>ReduceTask:负责Reduce阶段的整个数据处理流程
- MapReduce编程规范
用户编写的程序分为3个部分:Mapper、Reducer和Driver
Mapper阶段
1.用户自定义的Mapper要继承自己飞父类
2.Mapper的输入数据是KV对的形式(KV的类型可自定义)
3.Mapper中的业务逻辑写在map()方法中
4.Mapper的输出数据是KV对的形式(KV的类型可自定义)
5.map()方法(MapTask进程)对每一个<K,V>调用一次
MapReduce编程规范
1.用户自定义的Reducer要继承自己的父类
2.Reducer的输入数据类型对应Mapper的输出数据类型,也是KV
3.reducer的业务逻辑写在reduce()方法中
4.Reduce Task进程对每一组相同k的<k,v>组调用一次reduce()方法
Driver阶段
相当于YARN集群的客户端,用于提交我们整个程序到YARN集群,提交的是封装了MapReduce程序相关运行参数的job对象
- WorldCount案例实操
- Hadoop序列化
自定义bean对象实现序列化接口(Writable)
在企业开发中往往常用的基本序列化类型不能满足所有需求,比如在Hadoop内部传递一个bean对象,那么该对象就需要实现序列化接口
具体实现bean对象序列化步骤:
1.必须实现Writable接口
2.反序列化时,需要反射调用空参构造函数,所以必须有空参构造
public FlowBean()
{
super();
}
3.重写序列化方法
@Override
public void write (DataOutput out) throws IOException {
out.writeLong(upFlow);
out.writeLong(downFlow);
out.writeLong(sumFlow);
}
4.重写反序列化方法
@Override
public function readFields(DataInput in) throws IOException{
upFlow = in.readLong();
downFlow = in.readLong();
sumFlow = in.readLong();
}
5.注意反序列化的顺序和序列化的顺序完全一致
6.想要把结果显示在文件中,需要重写toString(),可用"\t"分开,方便后续用
7.如果需要将自定义的bean放在key中传输,则还需要实现Comparable接口,因为MapReduce框中的Shuffle过程要求对key必须能排序
@Override
public int compareTo(FlowBean o){
//倒叙排序,从大到小
return this.sumFlow > o.getSumFlow() ? -1 : 1;
}
MapReduce框架原理
- InputFormat数据输入
1.切片与MapTask并行度决定机制:
问题引入:MapTask的并行度决定Map阶段的任务处理并发度,进而影响到整个Job处理速度
思考:1G的数据启动8个MapTask,可以提高集群的并发处理能力,那么1K的数据也启动8个MapTask,会提高集群性能吗?
2.MapTask并行度决定机制:
数据块:Block时HDFS物理上吧数据分成一块块
数据切片:数据切片只是在逻辑上对输入进行分片,并不会在磁盘上切分成片进行存储
数据切片与MapTask并行度决定机制:
1 MapTask并行度由数据切片决定,切成3片就开3个MapTask
2 多文件如何切片:每个文件单独切片
虚拟存储切片最大值设置:
ConbineTextInputFormat.setMaxInputSplitSize(job, 4194304); //4M
注意:虚拟存储切片最大值设置最好根据实际的小文件大小情况来设置具体的值