HDFS二次开发常见问题
生活随笔
收集整理的這篇文章主要介紹了
HDFS二次开发常见问题
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
HDFS二次開發常見問題
問題描述
客戶開發了一個HDFS應用,此應用存在多個線程,需同時往HDFS組件上寫數據。在業務運行時,發現有業務線程和HDFS交互時,報如下異常:
...... 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) ......原因分析
經分析,捕捉到異常的業務應用線程確實有建立到HDFS組件連接,并且這個過程中此業務應用線程并沒close這個連接實例,連接初始化API示意代碼:
FileSystem hdfs1 = FileSystem.get(conf);再排查此業務應用代碼,發現在其他線程中有close連接實例的操作,關閉連接實例的API示意代碼:
hdfs1.close();深入分析發現:多個線程通過HDFS提供API申請并獲取到HDFS連接實例,但實際上是同一個連接實例,所以在同一個業務進程內,一旦一個線程close一個HDFS連接實例,其他線程即無法再使用先前所申請的連接實例。
如下是對這個問題的演示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"))); // 這里會失敗,因為上面已經把連 接實例關閉了。解決辦法
屬于HDFS機制,并不是bug。業務應用需根據自己的實際業務場景來確定如何使用HDFS連接。一般建議如下,供參考:
業務進程空間中,統一建立和管理(例如close)一個連接實例,各個線程共用,但不要直接管理此連接實例;
若實在有必要給一個線程單獨分配一個連接實例,可以按照HDFS機制,在創建連接實例時,指定不采用緩存中的連接實例,具體API的使用DEMO如下:
c. ......d. FileSystem hdfs1 = FileSystem.get(conf);e. conf.setBoolean("fs.hdfs.impl.disable.cache", true);//指定不采用緩存中的連接實例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"))); // 這里不會再拋出問題描述中的異常。轉載自:
https://forum.huawei.com/enterprise/zh/thread-471255.html
超強干貨來襲 云風專訪:近40年碼齡,通宵達旦的技術人生總結
以上是生活随笔為你收集整理的HDFS二次开发常见问题的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 分布式文件系统之ceph是什么?
- 下一篇: 从架构设计、部署方式、使用方法、应用场景