HDFS二次开发常见问题
HDFS二次開發(fā)常見問題
問題描述
客戶開發(fā)了一個(gè)HDFS應(yīng)用,此應(yīng)用存在多個(gè)線程,需同時(shí)往HDFS組件上寫數(shù)據(jù)。在業(yè)務(wù)運(yùn)行時(shí),發(fā)現(xiàn)有業(yè)務(wù)線程和HDFS交互時(shí),報(bào)如下異常:
...... Exception in thread "main" java.io.IOException: Filesystem closed at org.apache.hadoop.hdfs.DFSClient.checkOpen(DFSClient.java:498) at org.apache.hadoop.hdfs.DFSClient.getFileInfo(DFSClient.java:1869) at org.apache.hadoop.hdfs.DistributedFileSystem$26.doCall(DistributedFileSystem.java:1474) at org.apache.hadoop.hdfs.DistributedFileSystem$26.doCall(DistributedFileSystem.java:1470) at org.apache.hadoop.fs.FileSystemLinkResolver.resolve(FileSystemLinkResolver.java:81) at org.apache.hadoop.hdfs.DistributedFileSystem.getFileStatus(DistributedFileSystem.java:1 470) at org.apache.hadoop.fs.FileSystem.exists(FileSystem.java:1444) ......原因分析
經(jīng)分析,捕捉到異常的業(yè)務(wù)應(yīng)用線程確實(shí)有建立到HDFS組件連接,并且這個(gè)過程中此業(yè)務(wù)應(yīng)用線程并沒close這個(gè)連接實(shí)例,連接初始化API示意代碼:
FileSystem hdfs1 = FileSystem.get(conf);再排查此業(yè)務(wù)應(yīng)用代碼,發(fā)現(xiàn)在其他線程中有close連接實(shí)例的操作,關(guān)閉連接實(shí)例的API示意代碼:
hdfs1.close();深入分析發(fā)現(xiàn):多個(gè)線程通過HDFS提供API申請(qǐng)并獲取到HDFS連接實(shí)例,但實(shí)際上是同一個(gè)連接實(shí)例,所以在同一個(gè)業(yè)務(wù)進(jìn)程內(nèi),一旦一個(gè)線程close一個(gè)HDFS連接實(shí)例,其他線程即無法再使用先前所申請(qǐng)的連接實(shí)例。
如下是對(duì)這個(gè)問題的演示DEMO:
...... FileSystem hdfs1 = FileSystem.get(conf); FileSystem hdfs2 = FileSystem.get(conf); System.out.println("/user/tester1/spark-core is " + hdfs1.exists(new Path("/user/tester1/spark-core"))); System.out.println("/user/tester1/hive-date is " + hdfs2.exists(new Path("/user/tester1/hive-date"))); hdfs1.close(); System.out.println("/user/tester1/hive-date is " + hdfs2.exists(new Path("/user/tester1/hive-date"))); // 這里會(huì)失敗,因?yàn)樯厦嬉呀?jīng)把連 接實(shí)例關(guān)閉了。解決辦法
屬于HDFS機(jī)制,并不是bug。業(yè)務(wù)應(yīng)用需根據(jù)自己的實(shí)際業(yè)務(wù)場(chǎng)景來確定如何使用HDFS連接。一般建議如下,供參考:
業(yè)務(wù)進(jìn)程空間中,統(tǒng)一建立和管理(例如close)一個(gè)連接實(shí)例,各個(gè)線程共用,但不要直接管理此連接實(shí)例;
若實(shí)在有必要給一個(gè)線程單獨(dú)分配一個(gè)連接實(shí)例,可以按照HDFS機(jī)制,在創(chuàng)建連接實(shí)例時(shí),指定不采用緩存中的連接實(shí)例,具體API的使用DEMO如下:
c. ......d. FileSystem hdfs1 = FileSystem.get(conf);e. conf.setBoolean("fs.hdfs.impl.disable.cache", true);//指定不采用緩存中的連接實(shí)例f. FileSystem hdfs2 = FileSystem.get(conf);g.h. System.out.println("/user/tester1/spark-core is "i. + hdfs1.exists(new Path("/user/tester1/spark-core")));j. System.out.println("/user/tester1/hive-date is "k. + hdfs2.exists(new Path("/user/tester1/hive-date")));l.m. hdfs1.close();n. System.out.println("/user/tester1/hive-date is "+ hdfs2.exists(new Path("/user/tester1/hive-date"))); // 這里不會(huì)再拋出問題描述中的異常。轉(zhuǎn)載自:
https://forum.huawei.com/enterprise/zh/thread-471255.html
超強(qiáng)干貨來襲 云風(fēng)專訪:近40年碼齡,通宵達(dá)旦的技術(shù)人生總結(jié)
以上是生活随笔為你收集整理的HDFS二次开发常见问题的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 分布式文件系统之ceph是什么?
- 下一篇: 从架构设计、部署方式、使用方法、应用场景