假设我想知道每个单词在某些文本中出现的次数。
我的理解是,文本被分成多个部分,每个部分都传递给 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 中一样吗?
最佳答案
回顾一下 map-reduce 的工作原理:
在您引用的字数统计示例中, map 读取您提到的拆分/部分。
扫描单词部分时, map 不执行出现次数计数,
map 所做的是创建一个 <"word",1>
的键值对。 .这简化了 reducer 对词的下游聚合。
map 这样做是为了让处理特定 "word"
的 reducer可以收集所有 <"word",1>
元组发送它的方式,然后通过将所有 1 加在一起来生成计数。
简而言之,假设您有一个单词列表,如下所示:
cat
rat
mat
bat
cat
sat
bat
假设我们有 3 个映射器来处理文件拆分,如下所示:
为 mapper1 拆分 1:
cat
rat
mat
为 mapper2 拆分 2:
bat
cat
为 mapper3 拆分 3:
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更多细节。
关于hadoop - MapReduce中,为什么map函数在查找单词出现时输出1?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33470342/