0

我有两个来源的输入:

  1. 以表格形式输出地图,

    output.collect(new StockKey(Text(x+" "+id), new Text(id2)), new Text(data));
    
  2. 以表格形式输出地图,

    output.collect(new StockKey(new Text(x+" "+id), new Text(1), new Text(data));
    

工作配置:

 conf.setPartitionerClass(CustomPartitioner.class);
 conf.setValueGroupingComparatorClass(StockKeyGroupingComparator.class);

其中 StockKey 是 format 的自定义类(new Text(), new Text())

构造函数:

public StockKey(){
    this.symbol = new Text();
    this.timestamp = new Text();
}

分组比较器:

public class StockKeyGroupingComparator extends WritableComparator {

    protected StockKeyGroupingComparator() {
        super(StockKey.class, true);
    }  

    public int compare(WritableComparable w1, WritableComparable w2){
        StockKey k1 = (StockKey)w1;
        StockKey k2 = (StockKey)w2;

        Text x1 = new Text(k1.getSymbol());
        Text x2 = new Text(k2.getSymbol());

        return x1.compareTo(x2);

    }

}

但我没有从输入接收地图输出值

我只得到地图输出值到达减速器。我希望将两个地图输出中共有的符号 viz 的记录new Text(x+" "+id)分组到同一个 reducer。我在这里感到震惊。

请帮忙!

4

1 回答 1

1

为此,您需要一个适合如下的分区器:

  1. 您的映射器将一堆记录作为键/值对输出
  2. 对于每条记录,partitioner 都会被传递 key、value 和 reducer 的数量。分区器决定哪个减速器将处理记录
  3. 记录被运送到各自的分区(reducer)
  4. 运行 GroupingComparator 来决定哪些键值对被分组到一个迭代器中,以便对 reducer() 方法的单个调用
  5. 等等...

我认为默认分区器是根据您的键的整个值(这是默认行为)为每条记录选择减速器分区。但是您希望仅按部分键(仅符号而不是符号和时间戳)对记录进行分组。因此,您需要编写一个分区器来执行此操作并在驱动程序类中指定/配置它。

一旦你这样做了,你对比较器进行分组应该有助于按照你的意图对记录进行分组。

编辑:随机想法

  • 如果您将时间戳移到值上,您可能会让事情变得更容易,使键简单(只是符号)和值复杂(时间戳和值)。那么你就不需要分区器或分组比较器了。
  • 你没有说任何一种方式,但你确实使用了 MultipleInputs 类,对吧?这是为同一作业调用两个或多个映射器的唯一方法。
于 2012-11-04T21:46:44.157 回答