您好我已经编写了一个mapreduce作业,它通常解析XML文件。我能够解析XML文件并正确生成所有键值对。我有6个不同的键和相应的值。所以我并行运行了6种不同的减速器。
现在我面临的问题是reducer正在将两个不同的键值对放在同一个文件中,剩下的4个键值放在单个文件中。因此,简单地说,在reducer输出的6个文件中,我得到4个带有单键值对的文件和1个带有两个键值对的文件和1个没有任何内容的文件。
我尝试在谷歌和各种论坛上做研究,我得出的结论是我需要一个分区来解决这个问题。我是新的hadoop,所以有人可以解决这个问题,并帮助我解决这个问题。
我正在研究一个伪节点集群并使用Java作为编程语言。我无法在此处共享代码,但仍尝试简要描述问题。
让我知道需要更多信息,并提前感谢。
答案 0 :(得分:0)
6个减速器只有6个键不是hadoop的最佳利用率 - 虽然6个中的每一个都可以很好地使用单独的减速器但是不能保证。
密钥不能在reducers之间拆分,所以如果你的密钥少于6个,那么只有一部分reducer可以做任何工作。您应该考虑重新考虑您的密钥分配(也许输入文件适用于hadoop),并且可能使用一个系统,以便有足够的密钥在减速器中均匀分布。
编辑:我相信你所追求的是MultipleOutputFormat
,其方法为generateFileNameForKeyValue(key, value, name)
,允许你生成一个文件来写出每个键而不是每个{{1 }}
答案 1 :(得分:0)
默认情况下,Hadoop使用默认的Hash partitioner - click here,类似于
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()&amp; 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处理,你需要创建自己的分区器来获得你想要的东西。
如果您有任何疑惑,请查看this link以创建自定义分区程序,并使用Job类指定自定义分区程序,如下所示。
job.setPartitioner(<YourPartionerHere.class>);
希望这有帮助。