我写了一个自定义分区程序。当我有大于1的reduce任务数时,作业失败。这是我得到的例外:
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
。
感谢您对此的帮助。感谢。
答案 0 :(得分:21)
自定义Partitioner
计算出的分区号必须为非负数。尝试:
public int getPartition(weburl_compositeKey key, Text value, int numPartitions)
{
return (key.hashCode() & Integer.MAX_VALUE) % numPartitions;
}
答案 1 :(得分:4)
关于使用的警告:
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);
}
答案 2 :(得分:2)
或者您可以使用
public int getPartition(weburl_compositeKey key, Text value, int numPartitions)
{
return (key.hashCode() & Integer.MAX_VALUE) % numPartitions;
}