我正在运行一个Hadoop mapreduce流作业(mappers only作业)。在某些情况下,我的作业写入 stdout,从而创建一个非零大小的输出文件。在某些情况下,我的作业不会向 stdout 写入任何内容,但仍然会创建一个大小为 0 的输出文件。有没有办法避免在没有任何内容写入标准输出时创建这个大小为零的文件。
如果您不介意扩展当前的输出格式,则只需覆盖 OutputCommitter 即可在没有写入数据时"中止"提交任务阶段。
请注意,并非所有输出格式都显示空文件的文件字节为零(例如序列文件具有标头),因此您不能只检查输出文件大小。
查看以下文件的源:
- 输出提交器 - 基抽象类
- FileOutputCommitter - 大多数FileOutputFormat都使用此提交器,因此这是一个很好的起点。查看私有方法
moveTaskOutputs
,这是您的逻辑最有可能去的地方(如果未写入任何内容,则不复制文件)
你正在使用多输出吗?如果是,则 MultipleOutputs 会创建默认文件,即使化简器没有要写入输出的内容。要避免这种默认的零大小输出,您可以使用 LazyOutputFormat.setOutputFormatClass()
根据我的经验,即使您使用的是 LazyOutputFormat,在以下情况下也会创建零大小的文件:Reducer 有一些数据要写入(因此创建了输出文件),但 Reducer 在写入输出之前被杀死。我相信这是一个时序问题,所以你可能会观察到HDFS中只存在部分化简器输出文件,或者你可能根本不会观察到这一点。
例如。如果您有 10 个化简器,则可能只有"n"(n<=10) 个文件,其中一些文件的文件大小等于 0 字节。