您的位置:首页 > 运维架构

随手记点-mapreduce6

2016-03-29 17:10 288 查看

1.reduce的输入数据来自哪里?

答:reduce的输入数据源获取的是map阶段处理之后的数据,数据分布在diskSegment和内存中的InMemorySegment中。这些数据通过RawKVIteratorReader来读取。其中MergeQueue主要是对数据进行排序。

//ReduceTask中的run方法,这个是Reducer的输入,就是将收集到的map输出封装成KV
RawKeyValueIterator rIter = reduceCopier.createKVIterator(job, rfs, reporter);


2.map输出是(K,V),那么为什么reduce的输入是(K,list(V))?

答:Context继承了ReduceContext,实现的方法都在ReduceContext中。通过重写nextKeyValue()的方法来实现的。首先将数据的输入分为两层,第一层输入的是Iterator input,相当于一个缓冲层,在里面每次都存储下一个KV。在初始化时调用input.next()获取下一个使用的数据。通过nextKey中调用nextKeyValue()将数据从input中取出,并将下一个数据填充到input中。这样保证了key和value都是当前使用的。

第二层是当前封装成的Iterator,用以存储当前使用的KV,hasMore()的方法用以标示input中是否存在下一个数据,nextKeyIsSame()方法用以标示下一个K是否和当前K相同。在对List进行迭代的时候,如果是读取第一个数据直接返回,不是第一个数据则调用nextKeyValue()来获取下一个V的值返回,如果是最后一个value,那么nextKeyIsSame变为false,迭代结束。input中存在下一个可以使用的KV,在nextKey中会被读取。

3.相同的K可能会分配在不同的机器使用map处理,为什么reduce能够得到所有的数据,而且还是(K,list)形式的?

答:因为map处理完成的数据中有partition的值,可以指示具体的map结果是给哪个reduce进行处理的。在copy阶段,Reduce任务通过HTTP向各个Map任务拖取它所需要的数据,所以reduce可以得到所有的数据。至于为什么形式是(K,list)的上面已经解释了。

4.merge过程是怎么控制输入和输出的?

答:merge既包含了数据文件的合并,也包含了索引文件的合并。MapOutputBuffer中的mergeParts实现了Segment和文件中partition部分的对应。merge的输入来源于spill后的溢写文件,读入使用的是IFile.Reader类,写入使用的是IFile.Write类。

5.merge的设计框架是怎样的?

答:

Merger需要将多个文件和并

输入数据:数据可能同时是来自硬盘和内存中—->Segment解决数据来源问题

排序(Partition和Key)—->MergeQueue解决排序问题

输出数据:硬盘—->Merger.writeFile将数据写入硬盘

MergeQueue.merge还可以将数据写入硬盘

输出只返回Iterator—->Merger.merge仅仅返回一个MergeQueue ,作为reduce的输入
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  hadoop