代码之家  ›  专栏  ›  技术社区  ›  Thelight

自定义分区器,不设置减速器数量

  •  0
  • Thelight  · 技术社区  · 12 年前

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

    1 回复  |  直到 12 年前
        1
  •  0
  •   Community Mohan Dere    9 年前

    指定自定义分区器不会更改任何内容,因为分区数提供给分区器:

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

    定制定价器的设计取决于您。分区器的主要目标是避免倾斜,并在给定数量的分区上均匀分布负载。对于一些小型作业,可以决定只支持两个减速器,但如果您希望作业能够扩展,则必须将作业设计为使用任意数量的减速器运行。

    或者我必须根据输入的大小计算并设置减速器的数量,以获得最佳性能?

    这始终是您必须做的,并且与自定义分区器的使用无关。您必须设置减速器的数量,默认值为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 我不确定你所问的是解决实际问题的最佳方法。