现在的位置: 首页 > 综合 > 正文

hadoop map-reduce数据过程

2013年03月12日 ⁄ 综合 ⁄ 共 1082字 ⁄ 字号 评论关闭

对上一篇的补充,介绍map-reduce之间数据的流通,主要代码都在MapTask.java和ReduceTask.java两个文件中。

mapper的output.collect有两个分支,如果reduce number=0,则调用outputformat的recordwriter直接把key-value写到hdfs上。如果不为0,则key-value首先被记录在内存中(io.sort.mb),而且partition num也被计算然后记录下来;当内存满了,对内存做一次排序(排序会保证同一个partition的放在一起,同一个partition内部按照key进行排序),然后把结果输出到一个新的本地文件(还有一个新的index文件,为了便于shuffle过程中partition定位)。在内存文件向外输出的过程中,如果job设置了combiner,会在这个过程中调用combier后再输出;经过排序后,同一个key的数据都是相邻的,正好给combiner做合并。mapper在结束前,会调用一次merge过程,把多个小的本地文件合并成一个大的output文件。

reducer包含3个过程:shuffle(数据copy),sort(数据合并),reduce。reducer开始起固定数量的拉数据线程,一旦有mapper任务结束,就会去这个mapper机器,把属于这台机器的数据拉过来(用http方式)。sort实际上和shuffle是同时进行的,shuffle把来自多个mapper的output数据拿过来,当达到一定数量后(默认10个),会在后台把这些小文件合并成一个大的。当shuffle结束后,会再做一个merge,把所有的output文件合并成一个。这个数据就可以进入reduce接口了,它的output.collect直接进入hdfs。

小文件合并成大文件用的是MergeSort;mapper端merge多个spill文件,reducer端多个mapper输出数据的合并,都是用的这个接口。

mapper产生的key应该发到哪个reduce处理,是由partitioner控制的;partitioner通过key,和reduce数量,判定这个key发到哪。默认的动作是,key的hashcode求余reduce数量。所以默认情况下,key会平均分配到所有reduce上。如果要控制某个key到固定的reduce part,需要指定自己的partitioners。比如nid到nid%reducenum的reduce上,必须要实现自己的partitioner。

抱歉!评论已关闭.