【问题标题】:How to use combiner, when the output VALUE of reducer is null?当reducer的输出VALUE为null时,如何使用combiner?
【发布时间】:2023-03-22 14:25:01
【问题描述】:

当我尝试在我的 MR 工作中使用组合器时,出现以下异常

java.lang.NullPointerException
在 org.apache.hadoop.mapred.IFile$Writer.append(IFile.java:193)
在 org.apache.hadoop.mapred.Task$CombineOutputCollector.collect(Task.java:1315)

在 org.apache.hadoop.mapred.Task$NewCombinerRunner$OutputConverter.write(Task.java:1632)

原因是,我在 reducer 类中使用 null 作为我的输出 VALUE。 减速机代码:

public  static class reducer extends Reducer<Text,IntWritable,Text,IntWritable>{
            public void reduce(Text key, Iterable<IntWritable> values, Context context) throws IOException, InterruptedException{
                context.write(key, null);
            }
    }

当我删除组合器类 job.setCombinerClass(reducer.class); 作业正在成功。

如何实现组合器,我需要相同的减速器输出,即只有 KEY 作为输出?

【问题讨论】:

  • 为什么不使用 Java 的 Optional 或空对象?或者在你的 reducer 代码中检查 null 值。
  • 我不知道你为什么是null,你有没有考虑改用NullWritable
  • @YoungHobbit,我试过 NullWritable 但我遇到了同样的错误。只是为了测试我尝试了new IntWritable(),然后就没有问题了。但是输出不符合预期,最后追加了0。

标签: hadoop mapreduce


【解决方案1】:

这是不可能实现的。问题是IFile.java中的以下代码:

public void append(K key, V value) throws IOException {
    .....

    if (value.getClass() != valueClass)
        throw new IOException("wrong value class: "+ value.getClass()
                          +" is not "+ valueClass);

    .....

append()函数中,有一个检查:

if (value.getClass() != valueClass)

由于您将null 作为值传递,因此当NullPointerException 尝试在null 值上传递getClass() 时,会抛出getClass()

value.getClass()

所以,即使你使用NullWritable(又是一个类)并通过null,你仍然会得到NullPointerException

您应该通过传递 0(零)来管理,而不是传递 null

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-26
    • 1970-01-01
    • 1970-01-01
    • 2013-11-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多