【问题标题】:How to fix the "Illegal partition" error in hadoop?如何修复 hadoop 中的“非法分区”错误?
【发布时间】:2013-02-22 19:14:48
【问题描述】:

我已经编写了一个自定义分区器。当我的减少任务数量大于 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 并且此值的 mod 返回 -1

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

【问题讨论】:

    标签: java hadoop mapreduce


    【解决方案1】:

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

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

    【讨论】:

    • 这个问题有 3 个答案 - 两个正确,一个错误。太糟糕了,唯一不正确的一个获得了最高分和接受的答案标记。
    • @AndrewSkiba 感谢您指出这一点。我根据 Tanveer 的建议更正了答案。
    • 很高兴看到这一点。 GJ!
    【解决方案2】:

    关于使用的警告:

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

    【讨论】:

      【解决方案3】:

      或者你可以使用

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-04-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多