#MapReduce高级特性
一、序列化
- 核心接口:Writable
- 如果一个类实现了Writable该类的对象可以作为Key和Value
二、排序
- 规则:按照Key2排序(可以是基本数据类型,也可以是对象)
基本数据类型:数字(默认升序),字符串(默认字典顺序)
可以通过创建自己的比较规则改变排序(extends IntWritable.Comparator/extends Text.Comparator) - 对象
SQL排序:order by 列名、表达式、别名、序号 desc/asc(desc/asc只作用于最近的一列)
MapReduce排序:1.该对象必须是Key2;2.必须实现序列化接口Writable;3.对象必须是可排序的(自定义排序使用java.long 接口 Comparable) - MR排序分类
部分排序
全排序
辅助排序
二次排序三、分区
- 什么是分区:partition
- 查询:
1.没有分区:执行全表扫描
2.有分区,只扫描分区 - 分区的类型:
Orcale:
1.范围分区;
2.列表分区;
3.Hash分区;
4.Hash范围分区;
5.Hash列表分区
MR的分区:
默认情况下,MR的输出只有一个分区(一个分区就是一个文件)
自定义分区:按照字段进行分区(根据Map的输出<Key2,Value2>分区) - *通过SQL的执行计划,判断效率是否提高
四、合并
- 合并是一种特殊的Reduce
- 合并是在Map端执行一次合并,用于减少Mapper输出到Reduce的数据量,可以提高效率
- 平均值不能使用combiner
- 无论有没有combiner,都没不能改变Map和Reduce对应的数据类型
*MapReduce核心:Shuffle(洗牌)
- Hadoop3.X之前会有数据落地(产生I/O操作)
- map()方法写入数据到环形缓冲区
- 环形缓冲区达到80%后,发生溢写,进行分区、排序、合并(combiner可选)、归并
- 归并后,拷贝到内存缓冲
- 当内存不够时,溢出到磁盘
- 进行归并排序
- 相同key分组
- 传入Reduce()
*MapReduce优缺点
- 优点
1.易于编程
2.良好的拓展性
3.高容错性
4.适合处理PB级别以上的离线处理 - 缺点
1.不擅长做实时计算
2.不擅长做流式计算(MR的数据源事静态的)
3.不支持DAG(有向图)计算(Spark)
#Mapper,Reduce和Driver
Mapper阶段:
用户自定义Mapper类,要继承父类Mapper
Mapper的输入数据的kv对形式(kv类型可以自定义)
Mapper的map方法的重写(加入业务逻辑)
Mapper的数据输出kv对的形式(kv类型可以自定义)
map()方法(maptext进程)对每个<k,v>只调用一次Reducer阶段;
用户自定义Reduce类,要继承父类Reducer
Reducer的数据输入类型对应的是Mapper九段的输出数据类型
Reducer的reduce方法重写(加入业务逻辑)
ReduceText进程对每组的k的<k,v>组只调用一次Driver阶段
mr程序需要一个Driver来进行任务的提交,提交的任务是一个描述了各种重要信息的job
maptask流程
并行度:
一个job任务map阶段并行度由客户端所提交的任务决定
每一个split分配一个maptask并行处理
默认情况下,split大小=blocksize
切片是针对每一个文件单独切片
流程:
准备数据wordcount
创建客户端,提交任务程序driver
逻辑运算
向环形缓冲区写数据<k,v>(默认大小100M)
当环形缓冲区内存占用达到80%,进行溢写(HashPratitioner分区,key.compareTo排序(索引))
溢写到文件(保证分区且区内是有序的)
merge归并排序reducetask流程
reduceTask将相同分区的数据下载到reduceTask本地磁盘
再次合并文件,归并排序
合并过程中进行辅助排序
一次读一组,进行写出,生成结果文件
#Hadoop中所提供的数据序列化类型
- int > IntWritable
- float > FloatWritable
- long > LongWritable
- double > DoubleWritable
- String > Text
- boolean > BooleanWritable
- byte > ByteWritable
- Map > MapWritable
- Arry > ArryWritable
为什么要序列化?
存储“活的对象”
什么是序列化?
就是把内存中的对象,转换成字节序列以便于存储和网络传输
反序列化
就是将收到的字节序列或者硬盘的持久化数据,转换成内存中的对象
Java中的序列化
Serializable
为什么不用Java提供的序列化接口?
Java的序列化是一个重量级的序列化,一个对象被序列化后会附带很多额外的信息(校验信息,Header,继承体系等),不便于在网络中的高效传输,所以Hadoop开发了一套序列化鸡之(Writable),精简/高效
为什么序列化在Hadoop中很重要?
Hadoop通信是通过远程调用(rpc)实现的,需要进行序列化
特点:
1)紧凑
2)快速
3)可拓展
4)互操作
#MapReduce常用案例
- 一、数据去重
相同Key名交给同一地址进行处理,处理后输出给Reduce,Key值唯一,Value形成数组
- 二、多表查询(笛卡尔集:列数相加,行数相乘)
等值链接的处理过程(以表作为Value1)
Mapper阶段,通过分词后的列数或其他方法区分表
Mapper阶段,在字段前添加标识输出给Reduce
Reduce进行处理 - 三、自连接
同一个表经Mapper输出两次
非法数据要先经过处理(数据清理)
Reduce进行处理 - 四、倒排索引
- 五、单元测试(MRUnit)
#MapReduce重点
- 一、WordCount案例、流量汇总案例与涉及知识点
- 二、yran集群部署安装
- 三、job任务提交流程
- 四、辅助排序、分区排序
- 五、MapReduce整体流程
- 六、数据压缩