2015-04-23 2 views
2

J'ai un gros fichier gz d'environ 120Go. Je veux exécuter mapreduce sur cela, mais comme le fichier gz n'est pas splittable, un seul mappeur est capable de traiter ce fichier à la fois. Le fichier est présent sur hdfs et local à la fois. Option possible Je pense:Mapreduce sur gros fichier gz

1) Décompresser ce fichier gz et le stocker dans hdfs: Premièrement, il faudra trop de temps pour décompresser le fichier et mettre les données de décompression dans hdfs. De plus, je ne peux pas décompresser le fichier directement dans hdfs car hdfs n'a pas de commande zcat ou gunzip. Donc, je dois faire zcat a.gz | hdfs dfs put - /path/in/hdfs. Cela prendra aussi beaucoup d'espace dans hdfs (environ 4 fois plus de gz)

2) diviser le fichier en petit fichier (environ 1 Go chacun) et faire le traitement sur eux: meilleure option, mais malheureusement ne fonctionne pas. Je partage le gros fichier en petits fichiers en utilisant la commande split (également essayé chat a.gz | head -n), mais quand je courais Mapper sur eux, je reçois une erreur

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) et décompressez le fichier puis compresser à nouveau en bzip2: Cela prendra aussi beaucoup de temps.

S'il vous plaît me suggérer une autre idée d'y parvenir ou de modifier l'une des trois méthodes ci-dessus pour obtenir le succès (je préfère 2ème méthode: P)

Répondre

2

Je pense que vous pouvez aller avec l'option 3. Compresser le fichier dans Bzip2 donne l'avantage de l'utiliser directement dans le travail mapreduce. Puisque Bzip2 est splittable, vous n'avez pas besoin de le diviser manuellement en fichiers de 1Go (comme dans votre option2) et de les traiter, hadoop doit quand même les stocker dans des blocs de taille spécifiée et les traiter sur les splits d'entrée configurés. Donc, faire un pré-traitement de la compression du fichier dans Bzip2 devrait fonctionner correctement.