Hadoop自定义分区程序问题

时间:2012-10-25 20:02:25

标签: hadoop mapreduce partitioner

根据自定义分区程序的“getPartition”方法的输出,我遇到的问题是自定义中间键没有在我想要的分区中结束。我可以在我的映射器日志文件中看到分区器生成了预期的分区号,但是有时带有公共分区号的键不会在同一个reducer中结束。

具有共同“getPartition”输出的键如何以不同的reducers结束?

在所有“getPartition”调用完成后,我在mapper日志文件中注意到,对自定义中间键“hashCode”和“compareTo”方法进行了多次调用。映射器是否只是在分区排序中进行,还是这可能是问题的一部分?

我附加了自定义中介密钥和分区程序的代码。注意:我知道确切的1/2键将“useBothGUIDFlag”设置为true,而1/2将此设置为false(这就是为什么我将这些键分区为分隔空间的不同部分)。我也知道密钥似乎没有跨越到分区的另一半​​(即,“useBothGUIDFlag”键不会在“!useBothGUIDFlag”分区中结束,反之亦然),而是它们在其一半内混淆分区。

public class IntermediaryKey implements WritableComparable<IntermediaryKey> {

    public String guid1;
    public String guid2;
    public boolean useBothGUIDFlag;

    @Override
    public int compareTo(IntermediaryKey other) {
        if(useBothGUIDFlag)
        {
            if(other.useBothGUIDFlag)
            {
                return this.hashCode() - other.hashCode();
            }else{
                return 1;
            }
        }else{
            if(!other.useBothGUIDFlag)
            {
                return guid2.compareTo(other.guid2);
            }else{
                return -1;
            }
        }
    }

    @Override
    public int hashCode()
    {
        if(useBothGUIDFlag)
        {
            if(guid1.compareTo(guid2) > 0)
            {
                return (guid2+guid1).hashCode();
            }else{
                return (guid1+guid2).hashCode();
            }
        }else{
            return guid2.hashCode();
        }
    }

    @Override
    public boolean equals(Object otherKey)
    {
        if(otherKey instanceof IntermediaryKey)
        {
            return this.compareTo((IntermediaryKey)otherKey) == 0;
        }
        return false;
    }
}

public static class KeyPartitioner extends Partitioner<IntermediaryKey, PathValue>
{
    @Override
    public int getPartition(IntermediaryKey key, PathValue value, int numReduceTasks) {
        int bothGUIDReducers = numReduceTasks/2;
        if(bothGUIDReducers == 0)
        {
            return 0;
        }

        int keyHashCode = Math.abs(key.hashCode());
        if(key.useBothGUIDFlag)
        {
            return keyHashCode % bothGUIDReducers;
        }else{
            return (bothGUIDReducers + (keyHashCode % (numReduceTasks-bothGUIDReducers)));
        }
    }
}

1 个答案:

答案 0 :(得分:0)

问题最终出现在自定义密钥(IntermediaryKey)的序列化/反序列化中。正在阅读“useBothGUIDFlag”变量,与其本应相反。

在reducer中获取“mapred.task.partition”属性值有助于注意到已发生此交换。具有相反“useBothGUIDFlag”值的键似乎将转到正确的reducer。