在Hadoop中使用MultipleOutputs时,GZIP文件末尾的损坏

时间:2013-01-01 16:04:45

标签: hadoop gzip

我正在使用以下命令压缩Hadoop MR作业的输出

conf.setOutputFormat(TextOutputFormat.class);
TextOutputFormat.setCompressOutput(conf, true);
TextOutputFormat.setOutputCompressorClass(conf, GzipCodec.class);

我使用的是MultipleOutputs:

MultipleOutputs.addMultiNamedOutput(conf, "a", TextOutputFormat.class, Text.class, Text.class);
MultipleOutputs.addNamedOutput(conf, "b", TextOutputFormat.class, Text.class, Text.class);
LazyOutputFormat.setOutputFormatClass(conf, TextOutputFormat.class);

另外,每一项工作都很棒。我可以得到我想要的输出分区,我可以有gzip压缩输出。但是,在一起使用时,gzip压缩文件最终会被破坏。每个输出文件大约有25000行。当我做

之类的事情
hadoop dfs -cat output/*.gz | less +24000
一切看起来都很正常。但是如果我做的话

hadoop dfs -cat output/*.gz | less +40000

我收到错误,例如

zcat: stdin: invalid compressed data--crc error
zcat: stdin: invalid compressed data--length error
zcat: stdin: invalid compressed data--format violated

如果我重复第一个命令并开始扫描文件,最终我遇到一个不完整的行或几个非常长的,非常损坏的行之后出现上述错误之一(我认为它们很长,因为换行符也已损坏)和less不能再进一步了。

所以,我的问题是:有没有人见过这个,有没有办法解决它?

注意:我使用的是mapred API而不是mapreduce。我可以尝试转换为新的API,但如果我能找到使用mapred的解决方案,那将更可取。

1 个答案:

答案 0 :(得分:3)

只是一个猜测(没有看到你的reducer代码),但是你在reducer的清理方法中调用MultipleOutputs.close()(在MultipleOutputs的实例上,而不是一个不存在的静态方法)?

看起来gzip文件的最后一块没有被写入 - 与不调用上述方法一致