MapReduce组件
-
InputFormat类 :将文件分割成多个splits和每行怎么解析(recordReader)。
分片规则:max(minsplitSize,min(maxSplitSize,blockSize)) -
Mapper :对输入的每对<key,value>生成中间结果。
-
Partitioner: 对中间结果进行分区,默认通过hashPartitioner的getPartition()进行分区
-
Combiner: reduce子类,用于在map端对部分数据进行处理(通过key),减少reduce阶段的输入【将reduce压力分担给map一部分】
-
Reducer: 对所有的中间结果,进行处理。
-
outputFormat: 用来处理需要输出的数据
mapreduce执行流程
map阶段:InputFormat>>split>>map
- inputformat将输入文件切片split(getSplits()),每一个map处理一个split
- inputformat将split转换为Record循环交给map进行处理
- map处理Record生成中间结果
shuffle阶段
-
map阶段的shuffle:partitioner>>[combiner]FastSort>>[combiner]mergeSort
4. map将中间结果分区,并写入环形缓冲区,在写入磁盘根据partitioner进行分区,并执行FastSort进行排序
5. 如果配置了combiner,那么当环形缓冲区中的数据写入磁盘前会执行combiner进行合并【可以减少网络传输,但是可能会影响最终结果。】
6. 每次溢写(spill)会都生成一个分区并排序的spill文件
7. 当map阶段执行完毕时,会通过mergeSort将多个有序的spill文件进行合并,当spill文件数量大于3时会再次执行combiner进行合并,最终会生成一个分区且整体有序的文件作为reduce阶段的输入 -
reduce阶段的shuffle:copy>>mergeSort[combiner]
8. 当第一个map结束后,所有的reduce节点都会启动多个数据copy线程,将属于自己的数据copy到本地内存
9. Copy过来的数据会先放入内存缓冲区,如果内存缓冲区中大小足够时。会在内存中megerSort,如果内存大小不足时会将内存中的数据与本地磁盘中的数据进行mergeSort(类似溢写过程)
10. 如果reduce端存在溢写过程,那么会在溢写前执行combiner。当所有的map都结束后,copy、mergeSort过程也基本完成,此时会在Reduce节点中生成一个最终的输入文件
Reduce阶段: reduce>>outputFormat
- reduce循环读取输入文件中的Record进行处理,生成最终结果(个人猜测是通过inputFormat进行读取)
- outputFormat最终将结果输出
补充:(emm…我说为啥不能别人的文章都能改颜色我的不能改。。。csdn可以内嵌html标签。。。。。。)
以上还少了一个比较重要的东西:分组,众所周知mapreduce可以对key进行分区,而分组与分区的概念类似,都是用来划分数据的,只不过粒度更细。
- 当用户没有自定义partitioner时,会通过hashPartitioner进行分区。
- 当用户没有自定义分组时,会通过key的compareTo方法进行分组。
- 自定义分组需要实现WritableComparator接口
- 需要实现WritableComparator接口
这里存在一个误区:因为reduce方法参数是(key,values[],context),所以我认为最后输入到reduce的实参应该是 (key {1,2,3},context)这样的参数,所以我一直存在一个疑惑,那就是参数中的key怎样判断用哪一个value 的呢?于是我在reduce方法中打印了key,却发现recuce只执行了一次,但是其中的key却随着value的变化而变化了多次。于是我猜测应该是源码中迭代value时也将key的引用改变了。那么这样的话reduce中的输入应该是({key1 key2 key3},{1,2,3},context)。每次value发生变化时,key都会随之发生变化。
总结:一个reduce处理一个分区的数据,而分区中又划分为多个分组,当调用reduce方法处理完第一个键值对时,会判断下一个键值对是否与当前键值对同处于一个分组,如果属于同一分组就在当前reduce方法中执行。否则会重新调用一个reduce方法处理
推荐文章
http://www.cnblogs.com/intsmaze/p/6737337.html
https://www.linuxidc.com/Linux/2013-08/88603.htm