Hadoop:如何在同一个作业中输出不同的格式类型?
我想在一个作业中同时输出Hadoop:如何在同一个作业中输出不同的格式类型?,hadoop,mapreduce,gzip,lzo,Hadoop,Mapreduce,Gzip,Lzo,我想在一个作业中同时输出gzip和lzo格式 我使用了multipleoutput,并添加了两个命名输出,如下所示: multipleOutput.addNamedOutput(作业,“LzoOutput”、GBKTextOutputFormat.class、Text.class、Text.class) gbktexOutputFormat.setOutputCompressorClass(作业,LzoCodec.class) MultipleOutputs.addNamedOutput(作业,
gzip
和lzo
格式
我使用了multipleoutput
,并添加了两个命名输出,如下所示:
multipleOutput.addNamedOutput(作业,“LzoOutput”、GBKTextOutputFormat.class、Text.class、Text.class)代码>
gbktexOutputFormat.setOutputCompressorClass(作业,LzoCodec.class)代码>
MultipleOutputs.addNamedOutput(作业,“GzOutput”、TextOutputFormat.class、Text.class、Text.class)代码>
TextOutputFormat.setOutputCompressorClass(作业,gzip代码.class)代码>
(gbktexoutputformat
这里是我自己写的,扩展了FileOutputFormat
)
它们用于减速器,如:
multipleoutput.write(“LzoOutput”,nullwriteable.get(),value,”/user/hadoop/lzo/“+key.toString())代码>
multipleOutputs.write(“GzOutput”,nullwriteable.get(),value,”/user/hadoop/gzip/“+key.toString())代码>
结果是:
我可以在两个路径中获得输出,但它们都是gzip
格式
有人能帮我吗?谢谢
==========================================================================
更多:
我刚刚在FileOutputFormat
中查看了setOutputCompressorClass
的源代码,其中conf.setClass(“mapred.output.compression.codec”,codecClass,CompressionCodec.class)代码>
调用setOutputCompressorClass时,配置中的mapred.output.compression.codec似乎将被重置
那么实际的压缩格式就是我们最后设置的,我们不能在同一个作业中设置两种不同的压缩格式?或者忽略了其他内容?因此,作为一种解决方法,请尝试直接在配置中设置正确的outputCompressorClass
context.getConfiguration().setOutputCompressorClass(GzipCodec.class);
在对每个输出进行写调用之前。看起来,除了键类、值类和输出路径之外,任何输出格式配置参数都不能通过多路输出很好地处理,我们可能需要编写一些代码来弥补这一疏忽 您是否已确认GBKTextOutputFormat在用作未运行MultipleOutput的reducer中的唯一输出格式类型时有效?另外,在自定义输出格式类中,在getRecordWriter()方法中将压缩类设置为GzipCodec以外的其他类型?我指的是默认的压缩类…感谢您的回复!当只有一种输出格式类型时,GBKTextOutputFormat实际上运行良好。我将尝试在每次多次输出之前设置OutputCompressorClass。编写(…)
。我期待着听到它的进展。您实例化的MultipleOutputs对象实际上为每个输出缓存一个RecordWriter,并且该RecordWriter是在您第一次尝试向输出写入内容时构造的。我们已经讨论过的问题是,不同的输出会影响彼此的配置设置,然后记录编写器无法正确创建。理论上:)RecordWriter缓存在MultipleOutputs对象中,与您的点完全相同。RecordWriter的上下文是通过taskContext=getContext(…);,如果不等于null,则直接返回taskContext。这使得我们的setOutputCompressorClass在MultipleOutputs.write之前无法工作。因此,我将multipleOutput复制为另一个类,并修改getContext()函数。如果taskContext!=无效的现在一切似乎都正常了,接下来我应该做的是确保taskContext对于每个nameOutput只实例化一次,否则它将运行得太慢。非常感谢你!!!我没有想过创建一个新的多输出类。很酷。@thomaslee:看我对这个问题的回答: