2015-04-23 78 views
2

我有一个大小约120GB的gz文件。我想运行mapreduce,但由于gz文件不可拆分,只有一个映射器能够一次处理该文件。该文件存在于hdfs和本地文件中。 可能的选择我在想:Mapreduce上大gz文件

1)解压缩gz文件并将其存储在hdfs中:首先,需要太多时间来解压缩文件并将解压缩数据放入hdfs中。此外,我不能直接在hdfs中解压文件,因为hdfs没有zcat或gunzip命令。所以我必须做zcat a.gz | hdfs dfs put - /path/in/hdfs。 也需要这么多的空间在hdfs(约4倍于gz)

2)将文件分成小文件(每个大约1GB)并对它们进行处理:最好的选择,但不幸的是不工作。我分裂的大文件到采用分体式命令小档案(也试过猫a.gz |头-N),但是当我在其上运行映射器我得到错误

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)

回答

2

我认为你可以选择3去压缩文件在Bzip2中给出了直接在mapreduce作业中使用它的优点。由于Bzip2是可拆分的,您不需要手动将其拆分为1GB文件(如您的选项2)并对其进行处理,hadoop无论如何都必须将它们存储到指定大小的块中,并在所配置的输入拆分处理。因此,将文件压缩到Bzip2的预处理应该可以正常工作。