1

嗨,我写了一个 mapreduce 作业,它通常解析 XML 文件。我能够解析 XML 文件并正确生成所有键值对。我有 6 个不同的键和对应的值。所以我并行运行 6 个不同的减速器。

现在我面临的问题是减速器将两个不同的键值对放在同一个文件中,并将剩余的 4 个键值对放在单个文件中。因此,简而言之,在减速器输出的 6 个文件中,我得到 4 个具有单键值对的文件和 1 个具有两个键值对的文件和 1 个什么都没有的文件。

我尝试在谷歌和各种论坛上进行研究,唯一的结论是我需要一个分区器来解决这个问题。我是新的hadoop,所以有人可以对这个问题有所了解并帮助我解决这个问题。

我正在研究一个伪节点集群并使用 Java 作为编程语言。我无法在此处共享代码,但仍尝试简要描述问题。

让我知道需要更多信息,并提前致谢。

4

2 回答 2

0

默认情况下,Hadoop 使用默认的Hash 分区器 - 单击此处,类似于

public class HashPartitioner<K2, V2> implements Partitioner<K2, V2> {

  public void configure(JobConf job) {}

  /** Use {@link Object#hashCode()} to partition. */
  public int getPartition(K2 key, V2 value,
                          int numReduceTasks) {
    return (key.hashCode() & Integer.MAX_VALUE) % numReduceTasks;
  }

}

key.hashCode() & Integer.MAX_VALUE) % numReduceTasks 将返回一个介于 0 到 numReduceTasks 之间的数字,在您的情况下,范围为 0 到 5,因为 numRuduceTask=6

该行本身就存在问题 - 两个这样的语句可能会返回相同的数字。并且,因此两个不同的键可以进入同一个减速器。例如-

("go".hashCode() & Integer.MAX_VALUE) % 6

将返回您 4 并且,

("hello".hashCode() & Integer.MAX_VALUE) % 6

也会返回给你 4。

所以,我在这里建议的是,如果你想确保你的所有 6 个键都被 6 个不同的 reducer 处理,你需要创建自己的分区器来获得你想要的。

如果您有任何困惑,请查看此链接以创建自定义分区器,并使用 Job 类指定您的自定义分区器,如下所示。

job.setPartitioner(<YourPartionerHere.class>);

希望这可以帮助。

于 2013-05-11T06:07:38.240 回答
0

6 个减速器只有 6 个键并不是 hadoop 的最佳利用 - 虽然 6 个中的每一个都可以使用单独的减速器,但这并不能保证。

密钥不能在 reducer 之间拆分,因此如果您的密钥少于 6 个,则只有一部分 reducer 需要做任何工作。您应该考虑重新考虑您的键分配(也许输入文件对 hadoop 的适当性),并且可能使用一个系统,以便有足够的键在减速器之间均匀分布。

编辑:我相信您可能会追求的是MultipleOutputFormat,它具有方法generateFileNameForKeyValue(key, value, name),允许您生成一个文件以写入每个键,而不仅仅是每个Reducer.

于 2013-04-24T21:30:23.597 回答