J'essaie de charger des données volumineuses sur HDFS et j'ai parfois l'erreur ci-dessous. une idée pourquoi?
L'erreur:
org.Apache.hadoop.ipc.RemoteException: org.Apache.hadoop.hdfs.server.namenode.LeaseExpiredException: No lease on /data/work/20110926-134514/_temporary/_attempt_201109110407_0167_r_000026_0/hbase/site=3815120/day=20110925/107-107-3815120-20110926-134514-r-00026 File does not exist. Holder DFSClient_attempt_201109110407_0167_r_000026_0 does not have any open files.
at org.Apache.hadoop.hdfs.server.namenode.FSNamesystem.checkLease(FSNamesystem.Java:1557)
at org.Apache.hadoop.hdfs.server.namenode.FSNamesystem.checkLease(FSNamesystem.Java:1548)
at org.Apache.hadoop.hdfs.server.namenode.FSNamesystem.completeFileInternal(FSNamesystem.Java:1603)
at org.Apache.hadoop.hdfs.server.namenode.FSNamesystem.completeFile(FSNamesystem.Java:1591)
at org.Apache.hadoop.hdfs.server.namenode.NameNode.complete(NameNode.Java:675)
at Sun.reflect.GeneratedMethodAccessor16.invoke(Unknown Source)
at Sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.Java:25)
at Java.lang.reflect.Method.invoke(Method.Java:597)
at org.Apache.hadoop.ipc.RPC$Server.call(RPC.Java:557)
at org.Apache.hadoop.ipc.Server$Handler$1.run(Server.Java:1434)
at org.Apache.hadoop.ipc.Server$Handler$1.run(Server.Java:1430)
at Java.security.AccessController.doPrivileged(Native Method)
at javax.security.auth.Subject.doAs(Subject.Java:396)
at org.Apache.hadoop.security.UserGroupInformation.doAs(UserGroupInformation.Java:1127)
at org.Apache.hadoop.ipc.Server$Handler.run(Server.Java:1428)
at org.Apache.hadoop.ipc.Client.call(Client.Java:1107)
at org.Apache.hadoop.ipc.RPC$Invoker.invoke(RPC.Java:226)
at $Proxy1.complete(Unknown Source)
at Sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at Sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.Java:39)
at Sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.Java:25)
at Java.lang.reflect.Method.invoke(Method.Java:597)
at org.Apache.hadoop.io.retry.RetryInvocationHandler.invokeMethod(RetryInvocationHandler.Java:82)
at org.Apache.hadoop.io.retry.RetryInvocationHandler.invoke(RetryInvocationHandler.Java:59)
at $Proxy1.complete(Unknown Source)
at org.Apache.hadoop.hdfs.DFSClient$DFSOutputStream.closeInternal(DFSClient.Java:3566)
at org.Apache.hadoop.hdfs.DFSClient$DFSOutputStream.close(DFSClient.Java:3481)
at org.Apache.hadoop.fs.FSDataOutputStream$PositionCache.close(FSDataOutputStream.Java:61)
at org.Apache.hadoop.fs.FSDataOutputStream.close(FSDataOutputStream.Java:86)
at org.Apache.hadoop.io.SequenceFile$Writer.close(SequenceFile.Java:966)
at org.Apache.hadoop.io.SequenceFile$BlockCompressWriter.close(SequenceFile.Java:1297)
at org.Apache.hadoop.mapreduce.lib.output.SequenceFileOutputFormat$1.close(SequenceFileOutputFormat.Java:78)
at org.Apache.hadoop.mapreduce.lib.output.MultipleOutputs$RecordWriterWithCounter.close(MultipleOutputs.Java:303)
at org.Apache.hadoop.mapreduce.lib.output.MultipleOutputs.close(MultipleOutputs.Java:456)
at com.my.hadoop.platform.sortmerger.MergeSortHBaseReducer.cleanup(MergeSortHBaseReducer.Java:145)
at org.Apache.hadoop.mapreduce.Reducer.run(Reducer.Java:178)
at org.Apache.hadoop.mapred.ReduceTask.runNewReducer(ReduceTask.Java:572)
at org.Apache.hadoop.mapred.ReduceTask.run(ReduceTask.Java:414)
at org.Apache.hadoop.mapred.Child$4.run(Child.Java:270)
at Java.security.AccessController.doPrivileged(Native Method)
at javax.security.auth.Subject.doAs(Subject.Java:396)
at org.Apache.hadoop.security.UserGroupInformation.doAs(UserGroupInformation.Java:1127)
at org.Apache.hadoop.mapred.Child.main(Child.Java:264)
J'ai réussi à résoudre le problème:
Lorsque le travail est terminé, il supprime/data/work/folder. Si peu de travaux s'exécutent en parallèle, la suppression supprimera également les fichiers d'un autre travail. en fait, je dois supprimer/data/work /.
En d'autres termes, cette exception est levée lorsque le travail tente d'accéder à des fichiers qui n'existent plus
Je rencontre le même problème lorsque j'utilise spark streaming pour saveAsHadoopFile sur Hadoop (2.6.0-cdh5.7.1), bien sûr que j'utilise MultipleTextOutputFormat pour écrire des données différentes sur un chemin différent. Parfois l’exception que Zohar a dit se produirait. La raison en est que Matiji66 say:
un autre programme en lecture, écriture et suppression de ce fichier tmp provoque cette erreur.
mais la raison fondamentale pour laquelle il n'a pas parlé est le spéculateur hadoop:
Hadoop n'essaie pas de diagnostiquer et de corriger les tâches à exécution lente, mais plutôt de tenter de les détecter et d'exécuter des tâches de sauvegarde à leur place.
La raison en est que votre tâche s'exécute lentement, puis que hadoop exécute une autre tâche pour faire la même chose (dans mon cas, il s'agit de sauvegarder des données dans un fichier sur hadoop). Lorsqu'une tâche terminée, elle supprimera le fichier temporaire, et l'autre après fini, il supprimera le même fichier, alors il n'existe pas, donc l'exception
n'a pas de fichiers ouverts
arrivé
vous pouvez résoudre ce problème en fermant le spéculatif de spark et hadoop:
sparkConf.set("spark.speculation", "false");
sparkConf.set("spark.hadoop.mapreduce.map.speculative", "false");
sparkConf.set("spark.hadoop.mapreduce.reduce.speculative", "false")
Pour mon cas, un autre programme en lecture, écriture et suppression de ce fichier tmp provoque cette erreur . Essayez d'éviter cela.
J'utilise Sqoop pour importer dans HDFS et j'ai la même erreur. À l’aide des réponses précédentes, j’ai réalisé que j’avais besoin de supprimer le dernier "/" de
--target-dir/dw/data /
J'ai utilisé
--target-dir/dw/data.__ fonctionne bien
J'ai rencontré ce problème lorsque j'ai modifié mon programme afin qu'il utilise la méthode saveAsHadoopFile pour améliorer les performances. Dans ce scénario, je ne peux pas utiliser directement l'API DataFrame. voir le problème
La raison pour laquelle cela se produirait est essentiellement ce que Zohar a déclaré, la méthode saveAsHadoopFile avec MultipleTextOutputFormat ne permet pas à plusieurs programmes simultanément de sauvegarder des fichiers dans le même répertoire. Une fois le programme terminé, le répertoire commun _temporary dont les autres ont encore besoin sera supprimé. Je ne sais pas s'il s'agit d'un bogue dans l'API M/R. ( 2.6.0-cdh5.12.1 )
Vous pouvez essayer cette solution ci-dessous si vous ne pouvez pas repenser votre programme:
Il s'agit du code source de FileOutputCommitter dans l'API M/R: (vous devez télécharger une version correspondante)
package org.Apache.hadoop.mapreduce.lib.output;
public class FileOutputCommitter extends OutputCommitter {
private static final Log LOG = LogFactory.getLog(FileOutputCommitter.class);
/**
* Name of directory where pending data is placed. Data that has not been
* committed yet.
*/
public static final String PENDING_DIR_NAME = "_temporary";
Changements:
"_temporary"
À:
System.getProperty("[the property name you like]")
Compile la classe unique avec toutes les dépendances requises, puis crée un jar avec les trois fichiers de classe en sortie et place le jar dans votre chemin de classe. (le faire avant le pot original)
Ou, vous pouvez simplement mettre le fichier source dans votre projet.
Vous pouvez maintenant configurer le répertoire temporaire de chaque programme en définissant une propriété système différente.
J'espère que ça peut t'aider.
CAUSE PREMIÈRE
La stratégie de stockage a été définie sur le répertoire intermédiaire et, par conséquent, le travail MAPREDUCE a échoué.
<property>
<name>yarn.app.mapreduce.am.staging-dir</name>
<value>/user</value>
</property>
RÉSOLUTION
Répertoire intermédiaire de configuration pour lequel la stratégie de stockage n'est pas configurée. C'est à dire. modifier yarn.app.mapreduce.am.staging-dir dans yarn-site.xml
<property>
<name>yarn.app.mapreduce.am.staging-dir</name>
<value>/tmp</value>
</property>