我正在尝试将大数据加载到HDFS,我有时会收到以下错误。知道为什么吗?
错误:
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)
答案 0 :(得分:14)
我设法解决了这个问题:
当作业结束时,他会删除/ data / work /文件夹。如果并行运行的作业很少,则删除也将删除另一个作业的文件。实际上我需要删除/ data / work /.
换句话说,当作业尝试访问不再存在的文件时,抛出此异常
答案 1 :(得分:4)
当我使用spark streaming来保存AsHadoopFile到Hadoop(2.6.0-cdh5.7.1)时遇到同样的问题,当然我使用MultipleTextOutputFormat将不同的数据写入不同的路径。有时Zohar所说的异常会发生。原因是Matiji66说:
另一个程序读取,写入和删除此tmp文件会导致此错误。
但他没有谈到的根本原因是hadoop推测:
Hadoop不会尝试诊断和修复运行缓慢的任务,而是尝试检测它们并为它们运行备份任务。
所以真正的原因是,你的任务执行缓慢,然后hadoop运行另一个任务来做同样的事情(在我的情况下是将数据保存到hadoop上的文件),当两个任务的一个任务完成时,它将删除临时文件,其他完成后,将删除相同的文件,然后它不存在,所以异常
没有任何打开的文件
发生
你可以通过关闭spark和hadoop的推测来解决它:
sparkConf.set("spark.speculation", "false");
sparkConf.set("spark.hadoop.mapreduce.map.speculative", "false");
sparkConf.set("spark.hadoop.mapreduce.reduce.speculative", "false")
答案 2 :(得分:1)
对于我的情况,另一个程序读取,写入和删除此tmp文件会导致此错误。 尽量避免这种情况。
答案 3 :(得分:0)
ROOT CAUSE
存储策略已在暂存目录中设置,因此MAPREDUCE作业失败。
<property>
<name>yarn.app.mapreduce.am.staging-dir</name>
<value>/user</value>
</property>
解决方案
未设置存储策略的安装暂存目录。即修改yarn-site.xml中的yarn.app.mapreduce.am.staging-dir
<property>
<name>yarn.app.mapreduce.am.staging-dir</name>
<value>/tmp</value>
</property>
答案 4 :(得分:0)
我使用Sqoop导入HDFS并出现相同的错误。在之前的答案的帮助下,我意识到我需要删除
--target-dir /dw/data/
中的最后一个“/”
我用过
--target-dir /dw/data工作正常
答案 5 :(得分:0)
当我更改程序以使用saveAsHadoopFile方法来提高性能时遇到此问题,在这种情况下我无法直接使用DataFrame API。 see the problem
这种情况发生的原因基本上是Zohar所说的,带有MultipleTextOutputFormat的saveAsHadoopFile方法实际上并不允许多个程序同时运行以将文件保存到同一目录。一旦程序完成,它将删除其他人仍然需要的common _temporary目录,我不确定它是否是M / R API中的错误。 (2.6.0-cdh5.12.1)
如果您无法重新设计自己的计划,可以尝试以下解决方案:
这是M / R API中FileOutputCommitter的源代码:(必须下载相应的版本)
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";
的变化:
"_temporary"
要:
System.getProperty("[the property name you like]")
使用所有必需的依赖项编译单个类,然后使用三个输出类文件创建一个jar,并将jar放置到类路径中。 (在原来的罐子前制作)
或者,您只需将源文件放入项目中即可。
现在,您可以通过设置不同的系统属性来为每个程序配置临时目录。
希望它可以帮到你。