Hadoop reducer接收错误的数据

时间:2013-03-19 15:53:50

标签: java hadoop mapreduce hadoop-partitioning

我有一大堆JobControls同时运行,都使用相同的ControlledJobs集。每个JobControl按日期范围处理不同的输入/输出文件集,但它们都是类型。我观察到的问题是,reduce步骤正在接收设计为由处理不同日期范围的reducer处理的数据。日期范围由作业设置,用于确定输入和输出,并从缩减器中的上下文中读取。

如果我按顺序提交JobControls,这会停止,但这并不好。这是我应该用自定义分区程序解决的问题吗?如果我不知道哪个减速器正在处理我当前的日期范围,我怎么能确定钥匙的正确减速器?为什么实例化的Reducer不会被锁定到他们的JobControl?

我已经将所有JobControls,Jobs,Maps和Reduces编写为Java中的基本实现。

我正在使用带纱线的2.0.3-alpha。这与它有什么关系吗?

我必须小心分享代码,但这是一个经过消毒的映射器:

protected void map(LongWritable key, ProtobufWritable<Model> value, Context context) 
    throws IOException, InterruptedException {
  context.write(new Text(value.get().getSessionId()), 
                new ProtobufModelWritable(value.get()));
}

和减速器:

protected void reduce(Text sessionId, Iterable<ProtobufModelWritable> models, Context context) 
     throws IOException, InterruptedException {
  Interval interval = getIntervalFromConfig(context);
  Model2 model2 = collapseModels(Iterables.transform(models, TO_MODEL));

  Preconditions.checkArgument(interval.contains(model2.getTimeStamp()), 
      "model2: " + model2 + " does not belong in " + interval);
}

private Interval getIntervalFromConfig(Context context) {
  String i = context.getConfiguration().get(INTERVAL_KEY);
  return Utils.interval(i);
}

1 个答案:

答案 0 :(得分:0)

作为参考,我用2件事修好了。最重要的问题是,当我为每个区间创建单独的作业时,我给它们每个名称相同。通过将序列化间隔附加到作业名称,Hadoop知道将地图结果发送到哪个缩减器。

此外,我开始为每个作业创建单独的配置对象,而不是复制初始配置。这可能是不必要的,但至少我知道我不会犯错并开始共享相同的Configuration对象。