我的一个mapper会生成一些分布在文件中的日志,例如part-0,part-1,part-2等。现在每个日志都有一些查询和该查询的一些相关数据:
part-0
q score
1 ben 10 4.01
horse shoe 5.96
...
part-1
1 ben 10 3.23
horse shoe 2.98
....
and so on for part-2,3 etc.
现在相同的查询q,即上面的“1本10”,位于第1部分,第2部分等。
现在我必须编写一个地图缩减阶段,我可以在其中收集相同的查询并汇总(加起来)他们的分数。
我的映射器功能可以是一个标识,在reduce中我将完成此任务。
输出将是:
q aggScore
1 ben 10 7.24
horse shoe 8.96
...
似乎是一项简单的任务,但我无法想到如何进行此操作(阅读很多但不能继续)。我可以考虑通用算法问题,其中首先我将收集常见的查询,然后加上他们的分数。
任何有关pythonic解决方案或算法(map reduce)提示的帮助都会非常感激。
答案 0 :(得分:1)
这是MapReduce解决方案:
地图输入:每个输入文件(第0部分,第1部分,第2部分......)可以输入到单独的(单独的)地图任务中。
输入文件中的foreach输入行,
Mapper会发出<q,aggScore>
。如果单个文件中的查询有多个分数,Map会将它们全部加起来,否则如果我们知道每个查询只会出现在每个文件中一次,则map可以是每个输入发出<q,aggScore>
的标识函数按原样排列。
Reducer输入的格式为<q,list<aggScore1,aggScore2,...>
。Reducer操作类似于wordcount
的着名MapReduce示例。如果您使用的是Hadoop,则可以使用以下方法进行Reducer。
public void reduce(Text q, Iterable<IntWritable> aggScore, Context context) throws IOException, InterruptedException {
int sum = 0;
for (IntWritable val : aggScore) {
sum += val.get();
}
context.write(q, new IntWritable(sum));
}
该方法将对特定aggScores
的所有q
求和,并为您提供所需的输出。 reducer的python代码应如下所示(这里q
是键,aggScores
的列表是值):
def reduce(self, key, values, output, reporter):
sum = 0
while values.hasNext():
sum += values.next().get()
output.collect(key, IntWritable(sum))