8

我写了一个自定义分区器。当我的减少任务数量大于 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和模正在返回-1

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

4

3 回答 3

23

您的自定义计算的分区号Partitioner必须为非负数。尝试:

public int getPartition(weburl_compositeKey key, Text value, int numPartitions)
{
    return (key.hashCode() & Integer.MAX_VALUE) % numPartitions;
}
于 2013-02-22T19:38:39.680 回答
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);
}
于 2015-07-15T19:56:27.823 回答
2

或者你可以使用

public int getPartition(weburl_compositeKey key, Text value, int numPartitions)
{
    return (key.hashCode() & Integer.MAX_VALUE) % numPartitions;
}
于 2015-01-22T09:25:36.470 回答