根据自定义分区器的“getpartition”方法的输出,我遇到了一个自定义中间密钥不在我期望的分区中的问题。我可以在Map器日志文件中看到分区器生成预期的分区号,但是有时具有公共分区号的键不会在同一个缩减器中结束。
具有公共“getpartition”输出的键如何在不同的还原器中结束?
我注意到在mapper日志文件中,在所有的“getpartition”调用完成之后,对自定义中间键“hashcode”和“compareto”方法进行了许多调用。Map程序只是在分区内排序,还是这可能是问题的一部分?
我附上了自定义中介密钥和分区器的代码。注意:我知道有1/2的键将“usebothguidflag”设置为true,1/2的键将此设置为false(这就是为什么我将这些键划分为两部分分区空间)。我还知道,键似乎不会交叉进入分区的另一半(即,“usebothguidflag”键不会在“!同时使用guidflag“分区”,反之亦然),而是将它们混合在一半分区中。
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)));
}
}
}
1条答案
按热度按时间f45qwnt81#
问题最终出现在自定义密钥(intermediarykey)的序列化/反序列化中。“usebothguidflag”变量的读入方式与应该读入的相反。
在reducer中获取“mapred.task.partition”属性值有助于注意到发生了这种交换。具有相反“usebothguidflag”值的键似乎指向正确的减速机。