異常信息:
13/09/11 12:12:06 INFO hdfs.DFSClient: SMALL_BUFFER_SIZE is 512 org.apache.hadoop.ipc.RemoteException: org.apache.hadoop.hdfs.server.namenode.LeaseExpiredException: No leas e on /tmp/put_dir/20130911-121205-858/ie_ping1_access_log.2013091111.lzo File does not exist. Holder DFSClient_-2082829022 does not have any open files. at org.apache.hadoop.hdfs.server.namenode.FSNamesystem.checkLease(FSNamesystem.java:1623) at org.apache.hadoop.hdfs.server.namenode.FSNamesystem.checkLease(FSNamesystem.java:1614) at org.apache.hadoop.hdfs.server.namenode.FSNamesystem.completeFileInternal(FSNamesystem.java:1669) at org.apache.hadoop.hdfs.server.namenode.FSNamesystem.completeFile(FSNamesystem.java:1657) at org.apache.hadoop.hdfs.server.namenode.NameNode.complete(NameNode.java:714)
字面理解為文件操作超租期,實際上就是data stream操作過程中文件被刪掉了。之前也遇到過,通常是因為Mapred多個task操作同一個文件,一個task完成后刪掉文件導致。
不過這次在hdfs上傳文件時發生了這個異常,導致上傳失敗。google了一把,有人反饋跟dfs.datanode.max.xcievers參數到達上限有關。這個是datanode處理請求的任務
上限,默認為256,集群上面配置為2048.於是去所有datanode上面掃了一下log,發現果然出現了IOE:
java.io.IOException: xceiverCount 2049 exceeds the limit of concurrent xcievers 2048
翻源碼找了一下xcievers,有DataXcievers和DataXcieversServer兩個類,DataXcievers是DataXcieversServer啟動的一個線程,用於處理輸入輸出數據流,其run()
方法有如下判斷:
1 public void run() { 2 ... 56 int curXceiverCount = datanode.getXceiverCount(); 57 if (curXceiverCount > dataXceiverServer.maxXceiverCount) { 58 throw new IOException("xceiverCount " + curXceiverCount 59 + " exceeds the limit of concurrent xcievers " 60 + dataXceiverServer.maxXceiverCount); 61 }
xcievers超過限制拋了一個IOException,這反應到DFSClient端,就是正在操作的文件失去了響應,於是就出現了上面的租約超期異常。
解決方案:
繼續改大 xceiverCount 至8192並重啟集群生效。