2013-02-22 62 views
8

我写了一个自定义的分区程序。当我有大于1的减少任务数量时,该作业失败。这是我收到的例外:如何解决hadoop中的“非法分区”错误?

java.io.IOException: Illegal partition for [email protected] (-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

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

回答

21

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

public int getPartition(weburl_compositeKey key, Text value, int numPartitions) 
{ 
    return (key.hashCode() & Integer.MAX_VALUE) % numPartitions; 
} 
+0

非常感谢。它的工作:) – Maverick 2013-02-22 20:25:20

+0

@SumanBharadwaj不客气!请将答案标记为已接受。谢谢:) – harpun 2013-02-22 20:46:33

+0

这个问题收到3个答案 - 两个正确和一个不正确。太糟糕了,唯一不正确的人得到了最好的分数和接受的答案标记。 – 2015-12-31 09:35:44

2

或者你可以使用

public int getPartition(weburl_compositeKey key, Text value, int numPartitions) 
{ 
    return (key.hashCode() & Integer.MAX_VALUE) % numPartitions; 
} 
+0

谢谢。我用你的建议更新了我的答案。 – harpun 2016-01-04 19:37:11

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); 
}