MapReduce part1
MapReduce
1 是什么
MapReduce是Hadoop中的分布式计算框架,MR将计算任务抽象成Map和Reduce两个步骤,方便开发人员通过编写一个类似单机单线程程序,就可以直接进行分布式高并发应用的编写。
2 优缺点
2.1 优点
-
易于编程:
只需要编写一个Mapper类,一个Reducer类和一个Driver类,就可以完成分布式运算 -
扩展性:
与Hadoop集群一样,HDFS如果存储空间不够可以扩展集群规模增加磁盘容量,MR如果计算速度不足,可以增加集群规模扩展算力。 -
容错性:
MR运行时会启动多个线程分别运行在集群的不同机器上,如果某些线程计算失败,MR框架会自动将故障任务重新启动或者迁移到其他的节点上重新启动,保证任务结果的正确执行。 -
支持海量数据
GB\TB\PB
EB ZB BB
2.2 缺点
-
MR是一个分布式的批处理计算框架
-
不适合实时计算
在设计之初只考虑已经存储在HDFS上的确定的海量数据,没有考虑接入动态实时数据,所以由于设计缺陷导致,只支持离线计算 -
不适合包含多次聚合的DAG
MR过度抽象编程模型,导致每个MR任务只能包含一个reudce环节(聚合),如果任务的DAG中有多次聚合操作,就需要编写多个MR串联或者并联执行DAG,开发量和维护过于复杂。
3 编程开发
3.1. 编程模型
-
每个MR任务至少需要包含
-
1个Driver
MR任务的入口类,用来创建job对象,并组装MR任务 -
1个Mapper
一次拿到一组KeyValue进行处理,将处理完的结果写出到框架
org.apache.hadoop.mapreduce.Mapper
-
0个或者1个Reducer
一次拿到一组key和相同key对应的所有value,进行聚合,并将聚合完的结果写出到框架
org.apache.hadoop.mapreduce.Reducer
-
3.2 运行模式
3.2.1 Window本地运行
-
使用场景:用于开发和测试
-
环境准备:
-
添加winutils.exe
# 在D盘创建文件夹 D:\soft\hadoop-2.7.7 # 再在刚才的文件夹中创建bin文件夹 D:\soft\hadoop-2.7.7\bin # 将winutils.exe拷贝到上面目录中 D:\soft\hadoop-2.7.7\bin\winutils.exe # 添加系统环境变量 key: HADOOP_HOME value: D:\soft\hadoop-2.7.7 # 给PATH中添加 %HADOOP_HOME%\bin
-
添加hadoop.dll
将hadoop.dll复制到C:\Windows\System32
-
3.2.2 打jar包提交到集群运行
-
使用场景: 当测试任务逻辑没有问题后,生产环境中会将jar提交到集群运行
- 编译打包,并设置运行主类
- 上传到服务器
- hadoop jar 提交任务
4 Hadoop的序列化
-
由于Java自身的序列化框架对于MapReduce这种需要频繁进行网络IO和磁盘IO的计算任务来说过于复杂。所以Hadoop自己实现了一套轻量级的序列化机制 Writable。
-
MR要求Map和Reduce的输入输出类型都必须是Writable类型(实现Writable接口的可序列化对象)
-
在数据处理场景中一些时候需要开发者自己实现一些支持hadoop序列化的bean
-
比如:
- 需求:
从网站访问日志中统计
- 每天的访问次数(rCode=200) PV(PageVisit)
- 每天访问用户数 UV(UserVisit)
- 每个用户的请求流量
- 每个用户的响应流量
- 每个用户的请求响应码占比
- 需求:
字段名 | 英文名 | 类型 |
---|---|---|
ip | ip | String |
响应码 | rCode | int |
日期 | date | String |
上传流量 | upload | long |
下载流量 | download | long |
-
数据提取:
原始日志-> LogDetails对象
LogDetails对象是我们根据需求自己编写javaBean
如果需要将自定义Bean作为MR的Mapper或者Reducer的输入输出类型,那么自定义的Bean必须实现hadoop的序列化-
自定义Bean实现接口
org.apache.hadoop.io.Writable
-
实现序列化和反序列化方法
序列化: write(DataOutput out)
反序列化: readFields(DataInput in)- 注意:序列化和反序列化方法中需要将对象的属性按照一致的顺序分别写出和读取,写出时按照属性对应的类型选择写出方法
读取时按照属性的类型选择读取方法并复制给自己的成员属性
- 注意:序列化和反序列化方法中需要将对象的属性按照一致的顺序分别写出和读取,写出时按照属性对应的类型选择写出方法
-
为了方便进行输出,通常会重写toString方法
toString中通常选用一些属性内容中不好含的字符,比如\t
,|
-
如果要将自定义Bean放在Key的位置上,那么必须实现
org.apache.hadoop.io.WritableComparable
接口
WritableComparable
实现了Writable和Comparable
所以除了write和readField还需要实现Comparable中的compareTo()方法
-