为啥我的输出文件名为“part-r-xxxxx”,即使我没有提到任何减速器类?

Posted

技术标签:

【中文标题】为啥我的输出文件名为“part-r-xxxxx”,即使我没有提到任何减速器类?【英文标题】:Why are my output files named 'part-r-xxxxx', even though I have not mentioned any reducer class?为什么我的输出文件名为“part-r-xxxxx”,即使我没有提到任何减速器类? 【发布时间】:2015-08-15 23:08:44 【问题描述】:

我正在使用 Hadoop 2.6.0 的 Apache 发行版。我知道映射器的输出文件以每个映射器的“part-m-xxxxx”格式命名,而减速器的输出文件对于每个减速器都命名为“part-r-xxxxx”。我正在尝试一个简单的 Max-Temperature 用例,并且我没有在我的 Job 配置中设置任何减速器类。既然如此,输出文件不应该命名为'part-m-xxxxx'吗?请在下面找到我的主要课程:

public class MaxTemperature

    public static void main(String[] args) throws Exception
    
        Configuration conf = new Configuration();
        Job job = new Job(conf, "Max Temperture");
        job.setJarByClass(MaxTemperature.class);
        int noOfInputPaths = args.length-1;
        for (int i=0; i<noOfInputPaths; i++)
            System.out.println("Adding Input path: "+args[i]);
            FileInputFormat.addInputPath(job, new Path(args[i]));
        
        System.out.println("Output path: "+args[args.length - 1]);
        FileOutputFormat.setOutputPath(job, new Path(args[args.length - 1]));

        job.setMapperClass(MaxTemperatureMapper.class);
        //job.setReducerClass(MaxTemperatureReducer.class);
        //job.setNumReduceTasks(3);

        job.setOutputKeyClass(Text.class);
        job.setOutputValueClass(IntWritable.class);     

        job.setMapOutputKeyClass(Text.class);
        job.setMapOutputValueClass(IntWritable.class);

        System.exit(job.waitForCompletion(true)? 0 : 1);
    

【问题讨论】:

【参考方案1】:

如果 MapReduce 程序员没有使用 job.setReducerClass 设置 Reducer 类,则使用 IdentityReducer.class 作为默认值。 如果您只想对输入进行排序。例如,可以使用身份归约器来实现令人尴尬的并行算法,在这种算法中,您只需使用映射器来执行并行任务,但您希望对输出键值对进行排序。输出将是 part-r-xxxxx。

如果你设置了

job.setNumReduceTasks(0);

在这种情况下,reducer 不会运行,程序的输出将命名为 part-m-xxxxx。输出不会被排序。

【讨论】:

【参考方案2】:

正在使用默认的 Hadoop 输出格式,它将初始化并创建名为 (part-r-xxxxx) 的文件,与您在输出文件夹下看到的相同。

现在,创建的文件是空的,因为您没有在 reducer 部分写入(context.write(...))。但这并不能阻止它们在初始化期间被创建文件。

要阻止这种情况,您需要定义输出格式以表明您不期望任何输出。请参阅下文。

myJob.setOutputFormat(NullOutputFormat.class);

使用上述属性集,这应该确保您的零件文件根本不会被初始化。

注意:您可以使用 LazyOutputFormat 确保仅在有一些数据时才创建输出文件,并且不会初始化空文件。见下文。

LazyOutputFormat.setOutputFormatClass(myJob, TextOutputFormat.class);

希望这会有所帮助。

【讨论】:

将 OutputFormat 设置为 'NullOutputFormat.class' 导致没有创建输出。我实际上是想知道如何配置我的工作,如果我的问题得到解决并且使用 Mapper 本身提供相同的输出(例如,我们保证键只会出现一次的场景mapper 输入然后我想这可能),那么我们如何防止设置任何 reducer 任务并减少开销。 另外,当前生成的 part-r-00000 文件不是空的,它包含已排序但未合并的输出(通常是映射器输出)。我想那是因为我的 map 方法中有一个 context.write()。

以上是关于为啥我的输出文件名为“part-r-xxxxx”,即使我没有提到任何减速器类?的主要内容,如果未能解决你的问题,请参考以下文章

为啥下面的系统调用输出不重定向到文件?

为啥我的模块不在输出文件夹中?

为啥我的python脚本输出文件为空

为啥我的 Linux 版本的 logstash 不通过换行写入输出文件

为啥会创建“net6.0-windows”子文件夹?

为啥我的 avro 输出文件在我的猪工作中如此之小又如此之多?