【发布时间】:2012-10-25 20:02:25
【问题描述】:
根据自定义分区程序的“getPartition”方法的输出,我遇到了一个自定义中间键没有出现在我期望的分区中的问题。我可以在我的映射器日志文件中看到分区器产生预期的分区号,但是有时具有公共分区号的键不会在同一个减速器中结束。
具有公共“getPartition”输出的键如何在不同的减速器中结束?
我在映射器日志文件中注意到,在对自定义中间键“hashCode”和“compareTo”方法进行了多次调用之后,所有“getPartition”调用都被调用了。映射器只是在分区排序中进行还是可能是问题的一部分?
我附上了自定义中间键和分区器的代码。注意:我确切知道 1/2 的键将“useBothGUIDFlag”设置为 true,而 1/2 的键将此设置为 false(这就是我将这些键分区为分区空间的一半的原因)。我也知道键似乎没有跨入分区的另一半(即,“useBothGUIDFlag”键不会出现在“!useBothGUIDFlag”分区中,反之亦然),而是它们在它们的一半中混合分区。
public class IntermediaryKey implements WritableComparable<IntermediaryKey> {
public String guid1;
public String guid2;
public boolean useBothGUIDFlag;
@Override
public int compareTo(IntermediaryKey other) {
if(useBothGUIDFlag)
{
if(other.useBothGUIDFlag)
{
return this.hashCode() - other.hashCode();
}else{
return 1;
}
}else{
if(!other.useBothGUIDFlag)
{
return guid2.compareTo(other.guid2);
}else{
return -1;
}
}
}
@Override
public int hashCode()
{
if(useBothGUIDFlag)
{
if(guid1.compareTo(guid2) > 0)
{
return (guid2+guid1).hashCode();
}else{
return (guid1+guid2).hashCode();
}
}else{
return guid2.hashCode();
}
}
@Override
public boolean equals(Object otherKey)
{
if(otherKey instanceof IntermediaryKey)
{
return this.compareTo((IntermediaryKey)otherKey) == 0;
}
return false;
}
}
public static class KeyPartitioner extends Partitioner<IntermediaryKey, PathValue>
{
@Override
public int getPartition(IntermediaryKey key, PathValue value, int numReduceTasks) {
int bothGUIDReducers = numReduceTasks/2;
if(bothGUIDReducers == 0)
{
return 0;
}
int keyHashCode = Math.abs(key.hashCode());
if(key.useBothGUIDFlag)
{
return keyHashCode % bothGUIDReducers;
}else{
return (bothGUIDReducers + (keyHashCode % (numReduceTasks-bothGUIDReducers)));
}
}
}
【问题讨论】:
-
请发布您的分区器来源。你的钥匙是什么类型的?
-
另外,发送到两个不同 reducer 的键值的具体示例会有所帮助。
-
你怎么知道“有时具有公共分区号的键不会在同一个reducer中结束”?
-
我知道这一点,因为我将日志文件输出到 HDFS,指示每个减速器上的键。此外,从映射器日志文件中,我看到了 Hadoop 框架进行的“getPartition”调用的分区号。
-
那么在两个分区中出现的键的属性值是什么?你运行了多少个分区?
标签: hadoop mapreduce partitioner