【问题标题】:LeaseExpiredException: No lease error on HDFSLeaseExpiredException:HDFS 上没有租约错误
【发布时间】:2011-11-25 11:16:36
【问题描述】:

我正在尝试将大数据加载到 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)

【问题讨论】:

  • 你是如何加载数据的?
  • 您能在日志(namenode 和其他)文件中发布异常吗?

标签: hadoop hdfs


【解决方案1】:

我设法解决了这个问题:

当工作结束时,他会删除 /data/work/ 文件夹。如果并行运行的作业很少,则删除也会删除另一个作业的文件。实际上我需要删除 /data/work/。

换句话说,当作业尝试访问不再存在的文件时会引发此异常

【讨论】:

  • 你是如何解决这个问题的?通过设置 hive.exec.parallel=false ?哈,也许你没有使用 Hive ?
  • 我改变了我的 MR 的设计。我不会删除原件。
  • hive.exec.parallel=false 我需要把这个配置放在哪里?
【解决方案2】:

当我使用火花流将 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")

【讨论】:

    【解决方案3】:

    就我而言,另一个程序读取、写入和删除此 tmp 文件会导致此错误。 尽量避免这种情况。

    【讨论】:

      【解决方案4】:

      根本原因

      在暂存目录上设置了存储策略,因此 MAPREDUCE 作业失败。

      <property> <name>yarn.app.mapreduce.am.staging-dir</name> <value>/user</value> </property>

      分辨率

      设置未设置存储策略的暂存目录。 IE。修改 yarn-site.xml 中的 yarn.app.mapreduce.am.staging-dir

      <property> 
      <name>yarn.app.mapreduce.am.staging-dir</name> 
      <value>/tmp</value> 
      </property>
      

      【讨论】:

        【解决方案5】:

        我使用 Sqoop 导入 HDFS 并有同样的错误。在以前的答案的帮助下,我意识到我需要从

        中删除最后一个“/”
        --target-dir /dw/data/

        我用过

        --target-dir /dw/data
        工作正常

        【讨论】:

          【解决方案6】:

          我在更改程序以使用 saveAsHadoopFile 方法来提高性能时遇到了这个问题,在这种情况下我不能直接使用 DataFrame API。 see the problem

          之所以会出现这种情况,基本上是Zohar说的,MultipleTextOutputFormat的saveAsHadoopFile方法实际上是不允许多个程序同时运行将文件保存到同一个目录。一旦程序完成,它将删除其他人仍然需要的公共 _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 放置到您的类路径中。 (在原罐子之前做)

          或者,您可以简单地将源文件放入您的项目中。

          现在,您可以通过设置不同的系统属性来为每个程序配置临时目录。

          希望对你有帮助。

          【讨论】:

            猜你喜欢
            • 2023-03-14
            • 2021-03-31
            • 1970-01-01
            • 1970-01-01
            • 2015-11-14
            • 2020-06-22
            • 2021-05-22
            • 2015-09-12
            • 1970-01-01
            相关资源
            最近更新 更多