最近遇到一个有关hadoop的租赁问题,现在将其记录下来

12716 [main] WARN  org.apache.sqoop.tool.EvalSqlTool  - SQL exception executing statement: org.postgresql.util.PSQLException: , error: Failed to CREATE_FILE /hawq_data/ExtErrTbl/36f70260-6e94-44d0-900c-9d9210eeac5e/1545749452717109 for libhdfs3_client_random_1582511411_count_2_pid_506717_tid_140176099782080 on  

because this file lease is currently owned by libhdfs3_client_random_1582511411_count_2_pid_506733_tid_140176099782080 on  (extfmtcsv.c:189)  (seg1 :40000 pid=506717)
  详细:

	at org.apache.hadoop.hdfs.server.namenode.FSNamesystem.recoverLeaseInternal(FSNamesystem.java:3190)
	at org.apache.hadoop.hdfs.server.namenode.FSNamesystem.startFileInternal(FSNamesystem.java:2809)
	at org.apache.hadoop.hdfs.server.namenode.FSNamesystem.startFileInt(FSNamesystem.java:2698)
	at org.apache.hadoop.hdfs.server.namenode.FSNamesystem.startFile(FSNamesystem.java:2582)
	at org.apache.hadoop.hdfs.server.namenode.NameNodeRpcServer.create(NameNodeRpcServer.java:736)
	at org.apache.hadoop.hdfs.protocolPB.ClientNamenodeProtocolServerSideTranslatorPB.create(ClientNamenodeProtocolServerSideTranslatorPB.java:409)
	at org.apache.hadoop.hdfs.protocol.proto.ClientNamenodeProtocolProtos$ClientNamenodeProtocol$2.callBlockingMethod(ClientNamenodeProtocolProtos.java)
	at org.apache.hadoop.ipc.ProtobufRpcEngine$Server$ProtoBufRpcInvoker.call(ProtobufRpcEngine.java:640)
	at org.apache.hadoop.ipc.RPC$Server.call(RPC.java:982)
	at org.apache.hadoop.ipc.Server$Handler$1.run(Server.java:2351)
	at org.apache.hadoop.ipc.Server$Handler$1.run(Server.java:2347)
	at java.security.AccessController.doPrivileged(Native Method)
	at javax.security.auth.Subject.doAs(Subject.java:422)
	at org.apache.hadoop.security.UserGroupInformation.doAs(UserGroupInformation.java:1866)
	at org.apache.hadoop.ipc.Server$Handler.run(Server.java:2347)
 (786949)

由上面这个问题我们可以看出因为文件被hdfs给锁定了,导致了没法去重新创建,从而引发了sql错误。它为什么会被租赁呢,这个就需要说道hdfs的租赁机制了lease。下面是一个大佬的解答


1.      Lease 的机制:

hdfs支持write-once-read-many,也就是说不支持并行写,那么对读写的互斥同步就是靠Lease实现的。Lease说白了就是一个有时间约束的锁。客户端写文件时需要先申请一个Lease,对应到namenode中的LeaseManager,客户端的client name就作为一个lease的holder,即租约持有者。LeaseManager维护了文件的path与lease的对应关系,还有clientname->lease的对应关系。LeaseManager中有两个时间限制:softLimitand hardLimit。


软限制就是写文件时规定的租约超时时间,硬限制则是考虑到文件close时未来得及释放lease的情况强制回收租约。

LeaseManager中还有一个Monitor线程来检测Lease是否超过hardLimit。而软租约的超时检测则在DFSClient的LeaseChecker中进行。

当客户端(DFSClient)create一个文件的时候,会通过RPC 调用 namenode 的createFile方法来创建文件。进而又调用FSNameSystem的startFile方法,又调用 LeaseManager 的addLease方法为新创建的文件添加一个lease。如果lease已存在,则更新该lease的lastUpdate (最近更新时间)值,并将该文件的path对应该lease上。之后DFSClient 将该文件的path 添加 LeaseChecker中。文件创建成功后,守护线程LeaseChecker会每隔一定时间间隔renew该DFSClient所拥有的lease。


LeaseManagement是HDFS中的一个同步机制,用于保证同一时刻只有一个client对一个文件进行写或创建操作。如当 新建一个文件f时,client向NameNode发起一个create请求,那么leaseManager会想该client分配一个f文件的 lease。client凭借该lease完成文件的创建操作。此时其他client无法获得f的当client长时间(默认为超过1min)不进行操作 时,发放的lease将被收回。

最后解决办法 

我们只需要将软超时默认时间由原来的一分钟缩短就行了,当dfs客户端只要一分钟内没有操作就收回lease锁

hdfs.regionserver.lease.period=60000默认值 60000ms

 

参考地址:http://www.aboutyun.com/thread-17620-1-1.html