首页 > 解决方案 > Mapreduce 中的键是按值传递还是按引用传递?

问题描述

我创建了一个 MapReduce 作业,它会计算键的数量,然后按它们出现的次数对它们进行排序

在处理像这样的输入时

1A99
1A34
1A99
1A99
1A34
1A12

最终目标是一个像

1A99 3
1A34 2
1A12 1

我的地图阶段输出 <Key, 1> 类型的 <Text, Int Writable)

我的reduce阶段有3个阶段:设置我初始化一个数组列表来保存我的<Text,Int Wrtiable),然后是我总结Int Writables以获得计数然后将其插入我的数组的reduce阶段,最后是清理我按计数对数组列表进行排序。

数组列表中的值是我创建的 myObject 的一个对象,它将 Text 和 Int Writable 保存在一个元组中,我发现一个奇怪的是当我这样做的时候

new myObject(key, count)
    

最后,我在数组中的所有键都是相同的键,而只有计数不同。

但是,如果我这样做了

new myObject(new Text(key), count)

基本上复制了这个有效的密钥。

我找不到任何关于从映射器传递到减速器的密钥是否是通过引用的信息,但这似乎是为什么会发生这种情况的唯一合理解释。

标签: javamapreduce

解决方案


如果不查看实际代码,了解实际问题有些困难。但是,您似乎不需要 reduce 阶段的第 1 阶段和第 3 阶段。reducer 将得到一个key( Text) 和一个list of values( Iterable<IntWritable>)。这是在 map 阶段之后发生的中间 shuffle 阶段的结果。Iterable<IntWritable>在减少步骤中,您应该在(在您的情况下,将它们相加)上执行您需要执行的任何操作。那么这意味着对该密钥的处理已完成。使用context.write(key, result_of_operation),从 reducer 输出结果。

这就是数据集的处理方式:

Raw data
1A99
1A34
1A99
1A99
1A34
1A12

Some number of mappers will process this, say 3:
input to mapper 1
1A99
1A34
1A99

input to mapper 2
1A99

input to mapper 3
1A34
1A12

output of mapper 1
1A99, 1
1A34, 1
1A99, 1

output of mapper 2
1A99, 1

output of mapper 3
1A34, 1
1A12, 1

intermediate shuffle phase collects all values for keys
1A99, (1,1,1)
1A34, (1, 1)
1A12, (1)

Now, say we force one reducer (though there may be more than one)

reducer 1 input and output
1A99, (1,1,1) -> 1A99, 3
1A34, (1, 1) -> 1A34, 2
1A12, (1) -> 1A12, 1

可能有帮助的参考:

https://hadoop.apache.org/docs/stable/hadoop-mapreduce-client/hadoop-mapreduce-client-core/MapReduceTutorial.html#Example:_WordCount_v1.0


推荐阅读