【问题标题】:Java Hadoop - Reducer receives different values for the same key multiple times when using Combiner classJava Hadoop - 使用Combiner类时,Reducer多次接收相同键的不同值
【发布时间】:2013-11-04 13:18:43
【问题描述】:

我在 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 类设置为 Combiner。

总X求和:

地图输出:

X fieldX_1
X fieldX_2 
X fieldX_3
X ... 

减少输出:

X fieldX_1+fieldX_2+fieldX_3+...

奇怪的是,combiner/reducer 多次收到相同的 key:

X [fieldX_1 fieldX_1 fieldX_1 ... fieldX_1]
X [fieldX_2 fieldX_2 fieldX_2 ...]
X [fieldX_3 fieldX_3 fieldX_3 ...]
X ...

我对此很确定,因为我在 stderr 中记录了所有传递给 reduce 方法的每次调用以进行调试的所有内容。

我想添加一个更具体的例子:

数据:

1 field1_1 field2_1 field3_1 ... 10
2 field1_2 field2_2 field3_2 ... 20
3 field1_3 field2_3 field3_3 ... 30
4 field1_1 field2_1 field3_1 ... 10
5 field1_2 field2_2 field3_2 ... 40
6 field1_3 field2_3 field3_3 ... 20
...

地图输出:

X 10
X 20
X 30
X 10
X 40
X 20 

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

X [10 10 10 10]
X [20 20 20]
X [30 30 30 30 30 30 30]
X [40 40]

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

X 40
X 60
X 210
X 80

X 是一个常量标签(字段名)。 请注意,reducer 是使用相同的键 X 和 X 的相同值的集合调用的,例如[10 10 10 ...] 或 [30 30 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

如果我移除组合器,一切正常。 我知道Combiner 可能会被调用0、1 或多次,但是Reducer 呢?它应该只被调用一次,不是吗?

但更奇怪的是,我对字段分布重复了类似的过程,而这只发生在 X 求和问题中......

加权场分布

地图输出(示例字段 1):

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)+...
...

基本上,对于 field1 的每个值,我都在总结 fieldX 的所有相关值,并对几个字段(field1、field2、field3...)重复相同的过程。

对于那些发出的对,reducer 接收单个键 (field1(class1)) 和值数组 ([fieldX(class1)...]) 正常行为。

结论

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

这是我的代码中的错误还是我没有考虑到 Hadoop 的一些程序细节?

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

希望收到好的反馈。

【问题讨论】:

  • 你最终发现了什么?我有一个类似的问题,如果没有组合器,我会在减速器中获得多个相同键的列表,也就是说,而不是 {x,[1,2,3]} 我得到 {x,[1,2]} {x,[3 ]}?
  • 您使用的是哪种 Hadoop 发行版?
  • 由于一些限制,我使用的是 Hadoop 0.20.2。

标签: java hadoop key reduce


【解决方案1】:

发生的奇怪事情是组合器多次收到相同的密钥

这是可能的,因为 MapReduce 框架可能会多次调用组合器,请参阅JobConf#setCombinerClass()

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

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

【讨论】:

  • 谢谢。我期望在映射之后多次调用组合器,但我不知道它也可以在 reduce 中调用。我将 reducer 任务的数量设置为 1,因为我想将所有内容聚合在一个地方,但似乎生成了多个具有相同键的输出。有什么解决方法的建议吗?
  • 也许这个类有问题,你用它作为键?或者在你的减速器中,你为同一个键输出多个值?没有看到实际代码很难说。此外,您对减少过程/问题的描述相当复杂。尝试重新表述您的问题并提供更具体的示例。
  • 我编辑了这个问题,添加了一个更具体的例子。
  • 如果您使用单个减速器,您应该在减速器中收到一个键 X 的列表。您使用什么作为地图输出的键? Text 或一些自定义类?
  • 是的,该对的类型为: 用于输入和输出。因此,我可以看到重复的相同字符串键,这不是一种奇怪的行为吗?
猜你喜欢
  • 2014-01-22
  • 1970-01-01
  • 1970-01-01
  • 2019-04-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-12-24
  • 1970-01-01
相关资源
最近更新 更多