随手记点-mapreduce6

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的输入

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值