【发布时间】:2015-04-23 12:39:33
【问题描述】:
我有一个大小约为 120GB 的大 gz 文件。我想对其运行 mapreduce,但由于 gz 文件不可拆分,因此只有一个映射器能够一次处理该文件。该文件存在于 hdfs 和本地。 我正在考虑的可能选项:
1) 解压gz文件并保存在hdfs中:首先解压文件并将解压后的数据放入hdfs会花费太多时间。我也不能直接在 hdfs 中解压缩文件,因为 hdfs 没有 zcat 或 gunzip 命令。所以我必须做 zcat a.gz | hdfs dfs put - /path/in/hdfs 。
这也会在 hdfs 中占用大量空间(大约是 gz 的 4 倍)
2) 将文件拆分为小文件(每个大约 1GB)并对其进行处理:最佳选择,但不幸的是无法正常工作。我正在使用 split 命令将大文件拆分为小文件(也尝试过 cat a.gz | head -n),但是当我在它们上运行 mapper 时出现错误
Error: java.io.EOFException: Unexpected end of input stream
at org.apache.hadoop.io.compress.DecompressorStream.decompress(DecompressorStream.java:145)
at org.apache.hadoop.io.compress.DecompressorStream.read(DecompressorStream.java:85)
at java.io.InputStream.read(InputStream.java:101)
at org.apache.hadoop.util.LineReader.fillBuffer(LineReader.java:180)
at org.apache.hadoop.util.LineReader.readDefaultLine(LineReader.java:216)
at org.apache.hadoop.util.LineReader.readLine(LineReader.java:174)
at org.apache.hadoop.mapreduce.lib.input.LineRecordReader.nextKeyValue(LineRecordReader.java:185)
at org.apache.hadoop.mapred.MapTask$NewTrackingRecordReader.nextKeyValue(MapTask.java:553)
at org.apache.hadoop.mapreduce.task.MapContextImpl.nextKeyValue(MapContextImpl.java:80)
at org.apache.hadoop.mapreduce.lib.map.WrappedMapper$Context.nextKeyValue(WrappedMapper.java:91)
at org.apache.hadoop.mapreduce.Mapper.run(Mapper.java:144)
at org.apache.hadoop.mapred.MapTask.runNewMapper(MapTask.java:784)
at org.apache.hadoop.mapred.MapTask.run(MapTask.java:341)
at org.apache.hadoop.mapred.YarnChild$2.run(YarnChild.java:168)
at java.security.AccessController.doPrivileged(Native Method)
at javax.security.auth.Subject.doAs(Subject.java:415)
at org.apache.hadoop.security.UserGroupInformation.doAs(UserGroupInformation.java:1642)
at org.apache.hadoop.mapred.YarnChild.main(YarnChild.java:163)
3) 解压文件,然后再压缩成bzip2:同样需要很多时间。
请建议我任何其他想法来实现这一点或修改上述三种方法中的任何一种以获得成功(我更喜欢第二种方法:P)
【问题讨论】:
标签: hadoop mapreduce hdfs bzip2 gzip