我已经编写了一个自定义分区器。当reduce任务数大于1时,表示作业失败。这是我得到的例外:
java.io.IOException: Illegal partition for weburl_compositeKey@804746b1 (-1)
at org.apache.hadoop.mapred.MapTask$MapOutputBuffer.collect(MapTask.java:930)
at org.apache.hadoop.mapred.MapTask$OldOutputCollector.collect(MapTask.java:499)
我写的代码是
public int getPartition(weburl_compositeKey key, Text value, int numPartitions)
{
return (key.hashCode()) % numPartitions;
}
这使得key.hashCode()
等于-719988079
,并且该值的mod返回-1
。
感谢你在这方面的帮助。谢谢
自定义Partitioner
计算的分区数必须为非负数。尝试:
public int getPartition(weburl_compositeKey key, Text value, int numPartitions)
{
return (key.hashCode() & Integer.MAX_VALUE) % numPartitions;
}
关于使用的警告
public int getPartition(weburl_compositeKey key, Text value, int numPartitions)
{
return Math.abs(key.hashCode()) % numPartitions;
}
如果遇到key.hashCode()
等于Integer.MIN_VALUE
的情况,则仍然会得到负分区值。这是Java的一个奇怪之处,但Math.abs(Integer.MIN_VALUE)
返回Integer.MIN_VALUE
(如-2147483648中所示)。取模量的绝对值更安全,如
public int getPartition(weburl_compositeKey key, Text value, int numPartitions)
{
return Math.abs(key.hashCode() % numPartitions);
}
或者您可以使用
public int getPartition(weburl_compositeKey key, Text value, int numPartitions)
{
return (key.hashCode() & Integer.MAX_VALUE) % numPartitions;
}