JavaHadoop-Reducer在使用Combiner类时多次接收同一个键的不同值

JavaHadoop-Reducer在使用Combiner类时多次接收同一个键的不同值,java,hadoop,key,reduce,Java,Hadoop,Key,Reduce,我在Hadoop Java API(1.0.3)中编写了一个Map Reduce作业。 这项工作包括对我的数据中特定字段(X)的所有值求和,并创建其他字段的加权分布 输入: 1 field1_1 field2_1 field3_1 ... fieldX_1 2 field1_2 field2_2 field3_2 ... fieldX_2 3 field1_3 field2_3 field3_3 ... fieldX_3 由于数据中的任何一行都会发出一对数据,并且我需要使用一个reducer来

我在Hadoop Java API(1.0.3)中编写了一个Map Reduce作业。 这项工作包括对我的数据中特定字段(X)的所有值求和,并创建其他字段的加权分布

输入:

1 field1_1 field2_1 field3_1 ... fieldX_1
2 field1_2 field2_2 field3_2 ... fieldX_2
3 field1_3 field2_3 field3_3 ... fieldX_3
由于数据中的任何一行都会发出一对数据,并且我需要使用一个reducer来汇总所有的值,所以我想将Reduce类设置为组合器

总计X求和:

地图输出:

X fieldX_1
X fieldX_2 
X fieldX_3
X ... 
减少产量:

X fieldX_1+fieldX_2+fieldX_3+...
field1(class1) fieldX(class1)+fieldX(class1)+fieldX(class1)+...
field1(class2) fieldX(class2)+fieldX(class2)+fieldX(class2)+...
field1(class3) fieldX(class3)+fieldX(class3)+fieldX(class3)+...
...
奇怪的是,合并器/还原器多次收到同一个密钥:

X [fieldX_1 fieldX_1 fieldX_1 ... fieldX_1]
X [fieldX_2 fieldX_2 fieldX_2 ...]
X [fieldX_3 fieldX_3 fieldX_3 ...]
X ...
我确信这一点,因为我正在将传递给每次调用reduce方法进行dubugging的所有数据记录到stderr中

我想补充一个更具体的例子:

数据:

地图输出:

X 10
X 20
X 30
X 10
X 40
X 20 
减少输入(使用组合器):

减少输出(使用组合器):

X是一个常量标签(字段名)。 请注意,使用相同的键X和相同值X的集合调用减速器,例如[10 10…]或[30…]。 每个总和将分别输出。我的意思是,该算法运行良好,但在这个阶段需要额外的缩减步骤来汇总重复项

真实日志示例:

Nov 06, 2013 8:50:12 AM MYCLASS logInputError
WARNING: REDUCE-INPUT: X,[10.0]
Nov 06, 2013 8:50:12 AM MYCLASS logOutputError
WARNING: REDUCE-OUTPUT: X,10.0
Nov 06, 2013 8:50:12 AM MYCLASS logInputError
WARNING: REDUCE-INPUT: X,[25.865, 25.865]
Nov 06, 2013 8:50:12 AM MYCLAS logOutputError
WARNING: REDUCE-OUTPUT: X,51.73
Nov 06, 2013 8:50:12 AM MYCLASS logInputError
WARNING: REDUCE-INPUT: X,[1449271.4, 1449271.4, 1449271.4, 1449271.4, 1449271.4, 1449271.4, 1449271.4, 1449271.4, 1449271.4, 1449271.4, 1449271.4, 1449271.4, 1449271.4, 1449271.4]
Nov 06, 2013 8:50:12 AM MYCLASS logOutputError
WARNING: REDUCE-OUTPUT: X,2.0289798E7
Nov 06, 2013 8:50:12 AM MYCLASS logInputError
WARNING: REDUCE-INPUT: X,[514994.53, 514994.53, 514994.53, 514994.53, 514994.53, 514994.53, 514994.53, 514994.53, 514994.53, 514994.53, 514994.53, 514994.53, 514994.53]
Nov 06, 2013 8:50:12 AM MYCLASS logOutputError
WARNING: REDUCE-OUTPUT: X,6694929.0
Nov 06, 2013 8:50:12 AM MYCLASS logInputError
WARNING: REDUCE-INPUT: X,[1438665.5, 1438665.5, 1438665.5, 1438665.5, 1438665.5, 1438665.5, 1438665.5, 1438665.5, 1438665.5, 1438665.5, 1438665.5, 1438665.5, 1438665.5]
Nov 06, 2013 8:50:12 AM MYCLASS logOutputError
WARNING: REDUCE-OUTPUT: X,1.8702654E7
如果我拆下合路器,一切正常。 我知道合并器可能被调用0次、1次或多次,但是减速机呢?应该只调用一次,不是吗

但更奇怪的是,我对场分布重复了一个类似的过程,这只发生在X求和问题上

加权场分布

映射输出(示例字段1):

减少产量:

X fieldX_1+fieldX_2+fieldX_3+...
field1(class1) fieldX(class1)+fieldX(class1)+fieldX(class1)+...
field1(class2) fieldX(class2)+fieldX(class2)+fieldX(class2)+...
field1(class3) fieldX(class3)+fieldX(class3)+fieldX(class3)+...
...
基本上,对于field1的每个值,我将fieldX的所有相关值相加,并对几个字段(field1、field2、field3…)重复相同的过程

对于那些发出的对,reducer接收通常应该表现的单个键(field1(class1))和值数组([fieldX(class1)…])

结论

考虑的一点是,对于X求和问题,单键(X)映射的值数量等于数据的大小(行数)。同时,对于字段加权分布,值分布在字段包含的几个类标签之间

这是我的代码中的一个bug还是Hadoop的一些程序细节我没有考虑

根据M/R范式,Reducer类应该一次接收特定键的所有值,而不是划分成更多的分区

希望收到良好的反馈

奇怪的是,合并器多次收到同一个密钥

这是可能的,因为MapReduce框架可能多次调用组合器,请参见:

框架可以在两种情况下调用组合器0、1或多次 mapper和reducer任务。通常,组合器称为 排序/合并结果将写入磁盘。组合器必须:

  • 无副作用
  • 具有相同的输入和输出键类型以及相同的输入和输出值类型
奇怪的是,合并器多次收到同一个密钥

这是可能的,因为MapReduce框架可能多次调用组合器,请参见:

框架可以在两种情况下调用组合器0、1或多次 mapper和reducer任务。通常,组合器称为 排序/合并结果将写入磁盘。组合器必须:

  • 无副作用
  • 具有相同的输入和输出键类型以及相同的输入和输出值类型

非常感谢。我本来希望在映射之后调用组合器好几次,但我不知道在reduce中也可以调用组合器。我将reducer任务的数量设置为1,因为我想在一个地方聚合所有任务,但似乎生成了多个具有相同键的输出。有没有关于如何修复它的建议?也许你使用的作为键的类有问题?或者在减速机中为同一个键输出多个值?如果看不到实际的代码,很难判断。此外,您对reduce过程/问题的描述相当复杂。尝试重新表述您的问题,并提供一个更具体的示例。我编辑了问题,添加了一个更具体的示例。如果您使用单个减速机,您应该会收到减速机中键
X
的列表。您使用什么作为地图输出的键<代码>文本或某个自定义类?是的,该对类型为:用于输入和输出。因此,我可以看到相同的字符串键被复制,这不是一种奇怪的行为吗?谢谢。我本来希望在映射之后调用组合器好几次,但我不知道在reduce中也可以调用组合器。我将reducer任务的数量设置为1,因为我想在一个地方聚合所有任务,但似乎生成了多个具有相同键的输出。有没有关于如何修复它的建议?也许你使用的作为键的类有问题?或者在减速机中为同一个键输出多个值?如果看不到实际的代码,很难判断。此外,您对reduce过程/问题的描述相当复杂。尝试重新表述您的问题,并提供一个更具体的示例。我编辑了问题,添加了一个更具体的示例。如果您使用单个减速机,您应该会收到减速机中键
X
的列表。您使用什么作为地图输出的键<代码>文本或某个自定义类?是的,该对类型为:用于输入和输出。因此,我可以看到相同的字符串键被复制,这不是一种奇怪的行为吗?你最终发现了什么?我有一个类似的问题,没有组合器
field1_1 X_1
field1_2 X_2
field1_3 X_3
... 
field1(class1) fieldX(class1)+fieldX(class1)+fieldX(class1)+...
field1(class2) fieldX(class2)+fieldX(class2)+fieldX(class2)+...
field1(class3) fieldX(class3)+fieldX(class3)+fieldX(class3)+...
...