让我们说我想知道每个单词在某些文本中出现的次数。
我的理解是文本被分成几个部分,每个部分都传递给map
。然后,map
将获取每个部分的单词出现次数,并将结果传递给reduce
,如下所示:
for each word w in document:
occurrences[w] += 1
return occurrences
但是,根据MapReduce paper和wikipedia,map
只会为每个单词发出1,如下所示:
for each word w in document:
emit(w, 1)
这基本上与将文本部分直接传递给reduce
基本相同,因为它必须反复遍历每个单词?
另外,只是为了确保。如果我想用MapReduce对大型数组进行排序,那么map
会将它排序为数组的一部分,然后reduce
会合并已排序的数组,就像在mergesort中一样吗?
答案 0 :(得分:1)
仅查看map-reduce的工作原理:
在您引用的单词计数示例中,地图会按照您的提及读取分割/部分。
在扫描单词部分时,地图不会执行发生次数,
地图正在做的是创建一个<"word",1>
的键值对。这简化了reducer对单词的下游聚合。
映射正在执行此操作,以便处理处理特定"word"
的reducer可以收集所有发送方式的<"word",1>
元组,然后通过将所有1组合在一起来生成计数。
简而言之,假设你有一个单词列表如下:
cat
rat
mat
bat
cat
sat
bat
假设我们有3个映射器处理文件拆分,如下所示:
用于mapper1的Split1:
cat
rat
mat
map2的Split2:
bat
cat
用于mapper3的Split3:
sat
bat
mapper1将发出:
<cat,1>
<rat,1>
<mat,1>
Mapper2将发出:
<bat,1>
<cat,1>
Mapper3将发出:
<sat,1>
<bat,1>
虽然现实情况稍微复杂但理想情况下,每个单词都有一个减速器,并且每个映射器都会收到元组。
So reducer for cat receives:<cat,1> , <cat,1>
The reducer for rat receives: <rat,1>
The reducer for mat receives: <mat,1>
The reducer for bat receives: <bat,1>,<bat,1>
The reducer for sat receives: <sat,1>
每个reducer都会将它收到的所有元组相加并得到一个聚合值,如下所示:
<cat,2>
<rat,1>
<mat,1>
<bat,2>
<sat,1>
这就是map-reduce实现字数的方式。我们的想法是对计数操作进行并行化。
就你的排序问题而言,它更像是一种“捣蛋”技巧,而不是“合并”。 map-reduce框架将在内部对数据进行排序,并按排序顺序将其流式传输到reducer。
请查看此post了解详情。
答案 1 :(得分:0)
如果Mapper希望通过发射来执行 Reducer 作业,请使用Combiner,它是半减速器。 Combiner适用于Mapper的输出,并在此处执行reducer工作。
如果您实施客户分区程序,Shuffler和Reducer:它会更有效。
分区程序将确保Reducer进行负载平衡。
Shuffle 将确保将特定键形式的Mapper发送到特定的reducer。
Combiner 将执行mini reducer作业和Mapper的组合输出。
排序将在到达Reducer之前对Mapper输出的所有值进行排序。
在Combiner案例中,大多数时候Combiner&amp; Reducer类将被设置为相同的类。
即使使用合并器,输出也将是w,[1,1]而不是w,[2]
//Set Combiner class as WordcounReducer class.
job.setCombinerClass(WordcountReducer.class);
job.setReducerClass(WordcountReducer.class);
详细了解example和此SE question以及此SE Question 2