假设我想知道每个单词在文本中出现的次数。
我的理解是文本被分成几个部分,每个部分都被传递给map
。map
然后会获取每个部分的单词出现次数,并将结果传递给duce
,如下所示:
for each word w in document:
occurrences[w] += 1
return occurrences
然而,根据MapReduce论文和维基百科,map
只会为每个单词发出1,如下所示:
for each word w in document:
emit(w, 1)
这难道不是与直接将文本部分传递给duce
基本相同的事情吗,因为它无论如何都必须遍历每个单词?
另外,只是为了确保。如果我想使用MapReduce对一个大数组进行排序,map
会将它排序为数组的一部分,然后duce
会合并排序后的数组,就像在合并排序中一样?
只是为了回顾map-duce的工作原理:
在您引用的字数示例中,地图读取您提到的拆分/部分。
在扫描单词部分时,映射不执行出现计数,映射所做的是创建一个键值对
映射这样做是为了处理特定“word”
的还原器可以收集所有
简而言之,假设你有一个单词列表如下:
cat
rat
mat
bat
cat
sat
bat
假设我们有3个映射器来处理文件拆分,如下所示:
mapper1的Split1:
cat
rat
mat
mapper2的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>
每个还原器将它收到的所有元组相加并获得一个聚合值,如下所示:
<cat,2>
<rat,1>
<mat,1>
<bat,2>
<sat,1>
这就是map-duce实现单词计数的方式。这个想法是并行化计数操作。
就您关于排序的问题而言,它更像是一种“分桶”技巧,而不是“合并”。map-duce框架会在内部对数据进行排序,并按排序顺序将其流式传输到还原器。
请查看这篇文章了解更多详情。
如果您的Mapper想通过发射来执行减速器工作,请使用组合器,它是半减速器。组合器在Mapper的输出上工作并在此处执行减速器工作。
如果您实施客户分区器、Shuffler和Reducer:它会更有效。
分区器将确保减速器负载平衡。
Shuffle将确保特定的密钥表单映射器被发送到特定的减速器。
合成器将做小型减速器工作和Mapper的组合输出。
排序将在到达Reducer之前对Mapper输出的所有值进行排序。
在组合器案例中,大多数时候组合器
即使使用组合器,输出也将是w,[1,1]而不是w,[2]
//Set Combiner class as WordcounReducer class.
job.setCombinerClass(WordcountReducer.class);
job.setReducerClass(WordcountReducer.class);
看看详细的例子,这个SE问题,这个SE问题2