将snappy压缩文件加载到elastic mapreduce中

yzuktlbb  于 2021-06-03  发布在  Hadoop
关注(0)|答案(2)|浏览(437)

我在s3中有一堆snappy压缩的服务器日志,我需要在ElasticMapReduce上使用流处理它们。我如何告诉amazon和hadoop日志已经被压缩(在它们被拉入hfs之前!)以便在发送到流Map器脚本之前对其进行解压缩?
我能找到的唯一文档是:http://docs.aws.amazon.com/elasticmapreduce/latest/developerguide/hadoopdatacompression.html#emr-使用snappy,似乎指的是中间压缩,而不是到达hfs时压缩的文件。
顺便说一句,我主要在python中工作,所以如果你有boto的解决方案,我会给你加分!

stszievb

stszievb1#

假设您使用的是textinputformat(或其子类之一),则会自动处理扩展名为.snappy的压缩输入文件。
您可能需要考虑使用lzo压缩(.gz extension)而不是snappy。为了获得更好的压缩比和可拆分的输入文件,您放弃了一些压缩速度。cloudera在他们的博客中提到:
需要注意的一点是,snappy打算与容器格式一起使用,比如序列文件或avro数据文件,而不是直接在纯文本上使用,因为后者是不可拆分的,不能使用mapreduce并行处理。这与lzo不同,在lzo中可以索引lzo压缩文件以确定分割点,以便在后续处理中可以有效地处理lzo文件。

ni65a41a

ni65a41a2#

答案是,“做不到。”至少,对于将hadoop流应用到源于hadoop之外的snappy压缩文件的特定情况来说不是这样。
我(彻底地!)探索了两个主要的选项来得出这个结论:(1)尝试使用hadoop的内置snapy压缩,正如highlycaffinated所建议的那样,或者(2)编写我自己的流模块来使用和解压缩snapy文件。
对于选项(1),hadoop似乎在使用snappy压缩文件时向文件添加了一些标记。因为我的文件是用SnappyOutside hadoop压缩的,所以hadoop的内置编解码器无法解压缩文件。
此问题的一个症状是堆空间错误:

2013-04-03 20:14:49,739 FATAL org.apache.hadoop.mapred.Child (main): Error running child : java.lang.OutOfMemoryError: Java heap space
    at org.apache.hadoop.io.compress.BlockDecompressorStream.getCompressedData(BlockDecompressorStream.java:102)
    at org.apache.hadoop.io.compress.BlockDecompressorStream.decompress(BlockDecompressorStream.java:82)
    at org.apache.hadoop.io.compress.DecompressorStream.read(DecompressorStream.java:76)
    at java.io.InputStream.read(InputStream.java:85)
    ...

当我切换到一个更大的示例并启动mapred.child.java.opts设置时,出现了一个新错误:

java.io.IOException: IO error in map input file s3n://my-bucket/my-file.snappy

hadoop的snappy编解码器不能处理外部生成的文件。
对于选项(2),问题是hadoop流不区分\n、\r\n和换行符。由于快速压缩最终会在压缩文件中散布这些字节码,这是致命的。以下是我的错误跟踪:

2013-04-03 22:29:50,194 WARN org.apache.hadoop.mapred.Child (main): Error running child
java.lang.RuntimeException: PipeMapRed.waitOutputThreads(): subprocess failed with code 1
    at org.apache.hadoop.streaming.PipeMapRed.waitOutputThreads(PipeMapRed.java:372)
    at org.apache.hadoop.streaming.PipeMapRed.mapRedFinished(PipeMapRed.java:586)
    at org.apache.hadoop.streaming.PipeMapper.close(PipeMapper.java:135)
    at org.apache.hadoop.mapred.MapRunner.run(MapRunner.java:57)
    ...

通过对hadoop的java类做一点工作(例如,请参见此处),我们可能可以修复\r\n vs问题。但正如我最初所说,我的目标是在hadoop流模块中构建,而不涉及java。有了这个限制,似乎没有任何办法解决这个问题。
最后,我回到生成这个集群正在使用的文件的人那里,说服他们切换到gzip或lzo。
在选项(2)上,我试着用不同的字符(例如textinputformat.record.delimiter=x)分割记录,但感觉非常粗糙,无论如何都不起作用。
pps—另一种解决方法是编写脚本从s3下载文件,解压缩文件,然后运行-copyfromlocal将文件拉入hdfs。在计算上,这并没有错,但是从工作流的Angular 来看,它会带来各种各样的麻烦。

相关问题