这是我参与「第四届青训营 」笔记创作活动的第3天
Shuffle概述
hadoop中mapper之后,reducer之前的阶段称之为shuffle,是mapreduce的核心。
hadoop中,map负责数据的初级拆分获取解析,reduce负责最终数据的集总,除了业务逻辑的功能外,其他的核心数据处理都是由shuffle来支持。
简单总结
先把数据写入到缓冲区,每次写入之前要计算分区号,当要溢写时,会对数据进行排序,根据key进行排序(可以自己定义按什么来排序),溢写时如果设置了combiner(适合加减场景),会先对溢写的数据进行合并,每次溢写会生成spill文件,将多个spill文件进行合并,合并成总的文件,合并时如果片段数量大于等于3,这个时候combiner会继续运行,如果不大于则不会运行。在maptask输出时,还可以指定将合并后的数据以压缩格式输出。最终将文件写入磁盘。
Reduce阶段,通过shuffle线程拷贝指定分区的数据,拷贝后的数据会先在shuffle线程内存中进行合并,如果内存不够,也会进行多次溢写,最终对所有的数据进行一次归并排序。
分区
- 分区是在MapTask中通过Partitioner来计算分区号
- Partitioner的初始化
- 计算总的分区数partitions,取决于用户设置的reduceTask的数量
- partitions>1,默认尝试获取用户设置Partitioner,如果用户没有定义,那么会使用HashPartitioner,HashPartitioner根据key的hashcode进行计算,相同的key以及hash值相同的key会分到一个区
- partitions<=1,默认初始化一个Partitioner,这个Partitioner计算的所有的区号都为0
- 注意
- 通常在Job的设置中,希望将数据分为几个区,就设置reduceTask的数量为对应的数量!
- partitions=设置的reduceTask的数量,0<=分区器计算的区号 < partitions
排序
- 排序是MR框架在shuffle阶段自动进行
- 在MapTask端发生两次排序,在排序时,用户唯一可以控制的是提供一个key的比较器
- 设置key的比较器
- 排序的分类
- 全排序: 对所有的数据进行排序,指生成一个结果文件,这个结果文件整体有序
- 部分排序: 最终生成N个结果文件,每个文件内部整体有序
- 二次排序: 在对key进行比较时,比较的条件为多个
- 辅助排序: 在进入reduce阶段时,通过比较key是否相同,将相同的key分为1组
分组
- 分组通过分组比较器,对进入reduce的key进行对比,key相同的分为一组,一次性进入Reducer,被调用reduce方法
- 分组比较器的设置
- Reduce的细节
- 在进入reduce(),Reducer会自动实例化一个key,value,这个key-value在Redcuer工作期间,一直是一个不变的对象
- 每次迭代,reducer会把读到的新的key-value的属性值赋值给key-value!