大数据
Reduce源码分析
先拉取数据(拷贝Map的输出数据),再二次排序(分组的比较–迭代器),最后是reduce
ReduceTask
*rIter 用于代表reduce从所有Map拉取的数据,有归并功能(基于Map的归并方法) --真迭代器
*compartor 分组比较器
*getOutputValueGropingComparator
比较器取值过程
1查看用户是否设置分组比较器
2走Map端排序比较器
2-1先查看用户是否设置排序比较器
2-2如果没有设置取K自己的比较器
*runNewReducer
*createReduceContext
*reduceContext
*ReduceContextImpl
nextKey()
nextKeyValue() 作用:
1将Map端拉取的IO数据反序列化,简而言之,是对K,V赋值
2 nextKeyIsSame 取出下一组数据,利用分组比较器,比较前一条K与下一条K值
getCurrentKey()
getValues() 用到迭代器,也是在ReduceContextImpl方法中
注意nextKeyIsSame,其作用是预判断–比较前条和下条数据的K值是否一致使用的是分组比较器,这个值真假迭代器都要使用,真迭代器的nextKeyIsSame值除了Map输入文件的最后一条数据外可以为空其他时候都不会为空。但是假迭代器的nextKeyIsSame值在当前组不为空,原理如下
[外链图片转存失败(img-43kRL9QS-1563924807455)(C:\Users\86158\AppData\Roaming\Typora\typora-user-images\1560684975185.png)]
总结
比较器comparator 在Map中是排序比较器 在Reduce中是分组比较器
在排序比较器中有3个比较结果 >,<,= 2种取值过程(2)
在分组比较器中有2个比较结果 是,不是 3种取值过程(1,2)
比较器取值过程
1查看用户是否设置分组比较器
2走Map端排序比较器
2-1先查看用户是否设置排序比较器
2-2如果没有设置取K自己的比较器
nextKeyValue() 这个方法在Map端是 对k,v赋值的过程
在Reduce端 1对k,v赋值
2做预判断–比较前条和下条数据的K值是否一致(分组比较器)
reduce的迭代原理
假迭代器取的是真迭代器的内部数据,但是真迭代器会做预判断处理,当假迭代器使用nextKeyValue方法取值时,当假迭代器遇到前条数据与下条数据的K值不相等情况时,假迭代器执行完毕,会跳出循环。
这样保证了相同的K为一组,这组数据在reduce方法内进行迭代,所以假迭代器只能执行一组数据的归并
Map-Reduce不占用内存空间
Map不占用内存空间,只需要分配的溢写磁盘大小(默认100M),溢写出来的小文件都在磁盘上
Reduce拉取的Map数据在磁盘当中,只占用几条记录的内存