【问题标题】:Custom Partitioner, without setting number of reducers自定义 Partitioner,无需设置 reducer 数量
【发布时间】:2014-11-01 23:33:22
【问题描述】:

我们必须设置减速器的数量才能使用自定义分区器吗? 示例:字数问题,希望将所有停用词计数在一个分区中,并将剩余的单词计数到不同的分区。如果我将 reducer 的数量设置为两个并且停止词进入一个分区而其他词进入下一个分区,它将起作用,但我将 reducer 的数量限制为两个(或 N ),这是我不想要的.这里最好的方法是什么?或者我必须根据输入的大小来计算和设置减速器的数量以获得最佳性能?

【问题讨论】:

    标签: hadoop reducers partitioner


    【解决方案1】:

    指定自定义分区器不会改变任何事情,因为分区数是提供给分区器的:

    int getPartition(KEY key, VALUE value, int numPartitions) 
    

    如果您不设置分区器,则使用HashPartitioner。它的实现很简单:

    public int getPartition(K key, V value, int numReduceTasks) {
        return (key.hashCode() & Integer.MAX_VALUE) % numReduceTasks;
    }
    

    自定义分区器的设计取决于您。分区器的主要目标是避免偏差并将负载均匀分布在提供的分区数量上。对于一些小工作,可以决定只支持两个减速器,但如果你想让你的工作扩展,那么你必须设计你的工作来运行任意数量的减速器。

    或者我必须根据输入的大小来计算和设置reducer的数量以获得最佳性能?

    这始终是您必须做的,与自定义分区器的使用无关。您必须设置 reducer 的数量,默认值为 1,Hadoop 不会为您计算此值。

    如果您想将停用词发送到一个减速器,而将其他词发送到另一个减速器,您可以执行以下操作:

    public int getPartition(K key, V value, int numReduceTasks) {
        if (isStopWord(key) {
            return 0;
        } else {
            return ((key.hashCode() & Integer.MAX_VALUE) % (numReduceTasks - 1)) + 1;
        }
     }
    

    但是它很容易导致大的数据倾斜。第一个减速器将超载,并且比其他减速器需要更长的时间才能完成。在这种情况下,使用两个以上的减速器是没有意义的。

    可能是XY problem。我不确定你问的是解决实际问题的最佳方法。

    【讨论】:

    • 马修。感谢您的回复。我的问题是,我只希望“停用词”进入一个分区,其余的进入其他减速器,但我没有设置减速器的数量,而是将这项工作交给框架。所以在我的分区函数中我可以写: if (stopword) return 0; // 对于停用词分区,其他分区呢?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-31
    • 2013-03-29
    • 1970-01-01
    • 2018-04-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多