Hadoop(7)
MapReduce的介绍以及编程案例
文章目录
MapReduce介绍
MapReduce是一个分布式运算程序的 编程框架,是用户基于Hadoop开发数据分析应用的和新框架.MapReduce核心工能是将用户编写的业务逻辑代码和自带默认的组件整合成一个完整的分布式运算程序,并发运行在一个Hadoop集群上.
MapReduce的特点
优点
-
易于编程
MapReduce编程只需要实现几个接口,完成一个串行化的程序就可以
-
良好的扩展性
MapReduce程序可以运行在大量廉价的机器上运行,当计算资源得不到满足时,可以简单的通过增加机器数量来扩展集群的计算能力
-
高容错性
如果一台节点宕机,这台机器上的计算任务就可以自动转移到另外一台节点上运行
-
适合PB级以上海量数据的离线处理
MapReduce可以实现上千台机器并发工作,提供数据处理了的能力
缺点
-
不擅长实时计算
MapReduce无法在短时间内返回结果
-
不擅长流式计算
MapReduce的输入是静态的,而流式计算是动态的
MapReduce 核心过程
Map阶段
- 读取数据,并按行处理
- 对行进行切分(按照指定的字符,如空格)
- 整理成键值对
- 将键值对结果写入到磁盘
注意
1. Map阶段的MapTask完全并发执行,互不干扰
2. Map阶段对于每一个<K,V>键值对都会调用一次map()方法
Reduce阶段
- 读取Map阶段的键值对结果
- 对Map的结果进行归纳整理(计数)
- 将统计结果输出到磁盘(文件中)
注意
1. Reduce阶段的ReduceTask也是并发执行,互补干扰
2. Reduce阶段对于每一个<K,V>键值对都会调用一次reduce()方法
3. MapReduce编程模型只能包含一个Map阶段和一个Reduce阶段,如果用户的业务逻辑比较复杂,那就只能多个MapReduce程序串行执行
Hadoop序列化
Hadoop序列化介绍
Java序列化是一个重量级框架,一个对象被序列化后会附带很多额外信息,如果在的网络中传输会占用很大的资源,所以Hadoop自己有一套序列化机制 Writable
Hadoop序列化特点
- 紧凑: 高效使用空间
- 快速: 读写数据的额外开销小
- 可扩展: 随着通信协议的升级可升级
- 互操作: 支持多语言的交互
Hadoop序列化类型对比
Java类型 | Hadoop Writable类型 |
---|---|
Boolean | BooleanWritable |
Byte | ByteWritable |
Int | IntWritable |
Float | FloatWritable |
Long | LongWritable |
Double | DoubleWritable |
String | Text |
Map | MapWritable |
Array | ArrayWritable |
MapReduce编程主要流程
用户编写的程序分成三个部分:Mapper、Reducer和Driver
Mapper
- 自定义一个类,继承Mapper类(org.apache.hadoop.mapreduce包下的)
public class MyMapper extends Mapper<K1, V1, K2, V2> {
}
- 定义泛型类型(mapper的输入输出类型)
说明
这里要特别说明一下
Mapper
的泛型类型,四个类型分是:
<当前文件的偏移量,当前行的内容,map输出的key的类型,map输出的value的类型>
当前文件的偏移量: 是指相对于文件的开始,读取到哪里了,这里偏移量是一字节为单位,在实际编程中,这里直接使用LongWritable
就可以了,不需要特别关注当前行的内容: MapReduce对于文件是按行读取的,这里的偏移量和当前行的内容就组成了一个输入到mapper的键值对
map输出的key的类型: map处理当前行之后输出的键值对中的“键”
map输出的value的类型: map处理当前行之后输出的键值对中的“值”
如果白底黑字还是不理解,直接上图!
假设Mapper的四个泛型分别是<K1,V1,K2,V2>
- 重写map方法,将map阶段的业务逻辑在map方法中实现
@Override
protected void map(K1, V1, Context context) throws IOException, InterruptedException {
//map的方法体
}
说明
这里map方法的参数类型,前两个其实就是上面Mapper泛型的<K1,V1>,表示从文件输入到Mapper的键值对,因为之前说过,每个键值对都会调用一次map方法,所以这里的map方法参数类型就表示输入的键值对
第三个参数
Context
表示MapReduce的上下文,可以理解为MapReduce的运行环境,Mapper的输出(K2,V2)就是输出到Context中,一般来说第三个参数是固定的,直接写上Context
就好
- 将键值对输出
context.write(K2,V2 );
Reducer
- 自定义一个类继承Reducer类(org.apache.hadoop.mapreduce包下的)
public class WcReducer extends Reducer<K1, V1, K2, V2> {
}
- 定义泛型类型(reducer的输入输出类型)
说明
Reducer的泛型类型和Mapper的泛型类型作用是一样的,表示对于Reducer的输入和输出
其中K1,V1表示输入,K2,V2表示输出
因为Mapper的输出结果就是Reducer的输入,所以Reduce的输入类型和Mapper的输出类型是一致的,也就是说,Reducer的K1,V1等于Mapper的K2.V2
- 重写reduce方法,将Reduce阶段的业务逻辑在reduce方法中实现
@Override
protected void reduce(K1, V1', Context context) throws IOException, InterruptedException {
}
说明
这里注意的是reduce方法的参数,同map方法一样,前两个参数表示Reducer的输入类型,但是这里不同于map的是,因为map输出的不止是一个,而Key相同的键值对要汇聚到一个Reduce处理,所以reduce接收的应该是N多个键值对,所以reduce的第二个参数应该是一个迭代器,用于迭代遍历这些键值对
第三个参数同map,默认写Context就可以
- 输出结果
//输出统计结果
context.write(K2, V2);
Driver
定义该MapReduce程序的一些配置,相当于Yarn集群的客户端,用于提交该MapReduce程序到Yarn集群
- 获取Job实例
- 配置