2013-02-22 68 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); 
}