如何解决hadoop中的“非法分区”错误?

时间:2013-02-22 19:14:48

标签: java hadoop mapreduce

我写了一个自定义分区程序。当我有大于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

感谢您对此的帮助。感谢。

3 个答案:

答案 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;
}