[HDFS-inotify]“IOException:客户端在读取文件后停止

31 篇文章 0 订阅

1.我想写下一个在创建时在特定位置读取文件的代码(使用inotify)
    所以我在github中修改了基于“hdfs-inotify-example”的示例代码
https://github.com/onefoursix/ HDFS-的inotify-示例/斑点/主/ SRC /主/ JAVA / COM / onefoursix / HdfsINotifyExample.java

2.当重命名为https://github.com/onefoursix/hdfs-inotify-example/commit/82485881c5da85a46dd1741c2d8420c7c4e81f93时,我已将读取和打印行的代码更改为控制台

case RENAME:
    Event.RenameEvent renameEvent =(Event.RenameEvent)event; 
    配置conf = new Configuration(); 
    conf.set(“fs.defaultFS”,defaultFS); 
    System.out.println(renameEvent.getDstPath()+“”+ inputPath.getPath()); 
    if(renameEvent.getDstPath()。startsWith(inputPath.getPath())){ 
        //尝试读取文件
        try(FileSystem fs = FileSystem.get(conf)){ 
            Path filePath = new Path(defaultFS + renameEvent.getDstPath() ); 
            BufferedReader br = new BufferedReader(new InputStreamReader(fs.open(filePath))); 
            字符串行; 
            line = br.readLine(); 
            while(line!= null){
                的System.out.println(线); 
                line = br.readLine(); 
            } 
            br.close(); 
        } 
    }

它有效。但是我在文件读取后的下一个eventStream.take()中遇到了IOException。如果我不读取hdfs上的文件,就不会发生这种情况。
------------- CODE ------------- 
DFSInotifyEventInputStream eventStream = admin.getInotifyEventStream(); 
EventBatch batch = eventStream.take();

------------- LOG ------------- 
Cazens-MacBook-Pro:hdfs-inotify-example Cazen $ java -jar target / hdfs-inotify-example -uber.jar hdfs:// localhost:8032 / cazen / lastReadTxid 
= 0 
log4j:WARN找不到logger(org.apache.hadoop.util.Shell)的appender。
log4j:WARN请正确初始化log4j系统。
log4j:WARN有关详细信息,请参阅http://logging.apache.org/log4j/1.2/faq.html#noconfig
TxId = 3134 
事件类型= CREATE 
  路径= /cazen/test2.txt._COPYING_ 
  owner = Cazen 
  ctime = 1461850245559 
TxId = 3138 
事件类型= CLOSE 
TxId = 3139 
事件类型= RENAME 
/cazen/test2.txt / cazen /
--------------------文件开始
输入文件文本示例LOL 
--------------------文件END 
异常在线程“main”中java.io.IOException:客户端
在org.apache.hadoop.ipc.Client.call(Client.java)的org.apache.hadoop.ipc.Client.getConnection(Client.java:1507)
处停止:1451) atg.apache.hadoop.ipc.Client.call(
Client.java:1412 

位于com.sun.proxy的org.apache.hadoop.ipc.ProtobufRpcEngine $ Invoker.invoke(ProtobufRpcEngine.java:229)。位于sun.reflect.NativeMethodAccessorImpl.invoke0 (本机方法)的
org.apache.hadoop.hdfs.protocolPB.ClientNamenodeProtocolTranslatorPB.getEditsFromTxid(ClientNamenodeProtocolTranslatorPB.java:1511)
上的$ Proxy9.getEditsFromTxid(未知来源)
在sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)的 sun.reflect.DelegatingMethodAccessorImpl.invoke 
(DelegatingMethodAccessorImpl.java:43)
atg的java.lang.reflect.Method.invoke(Method.java:497)
。 位于com.sun.proxy的
org.apache.hadoop.io.retry.RetryInvocationHandler.invoke(RetryInvocationHandler.java:102)的apache.hadoop.io.retry.RetryInvocationHandler.invokeMethod(RetryInvocationHandler.java:191)
。$ Proxy10.getEditsFromTxid (未知来源)
在org.apache.hadoop.hdfs.DFSInotifyEventInputStream.poll(DFSInotifyEventInputStream.java:111)
在org.apache.hadoop.hdfs.DFSInotifyEventInputStream.take(DFSInotifyEventInputStream.java:224)
在com.onefoursix.HdfsINotifyExample.main (HdfsINotifyExample.java:40)

我可能写错了代码。如果有人已经知道这种情况,我可以问一下原因吗?
任何意见,将不胜感激。

 

这看起来像是因为这会导致关闭FileSystem对象的意外副作用。Hadoop在内部缓存FileSystem类的实例,并且可以将同一实例返回到多个调用站点。即使在一个呼叫站点关闭它之后,其他呼叫站点仍然可以保持对同一个FileSystem实例的引用。关闭FileSystem实例使其无法使用。

HdfsAdmin#getInotifyEventStream可能使用您自己的FileSystem.get调用返回的相同FileSystem实例。通过关闭它(使用try-with-resources),该FileSystem实例对于检索inotify事件的后续调用无效。

FileSystem缓存是一个相当常见的混淆源。但是,它的当前行为是设计考虑的。出于向后兼容的原因,我们不能轻易改变其行为以帮助解决这类令人困惑的情况。(抱歉!)

一些尝试的建议:

1.只是不要关闭FileSystem。即使您没有明确地关闭它,它也会在进程拆卸时通过关闭钩子关闭。从资源管理的角度来看,这肯定是错误的,但很多应用程序都是这样工作的。

2.调用FileSystem#newInstance而不是FileSystem#get。newInstance方法保证返回该调用站点唯一的实例,而不是其他调用站点可能使用的共享实例。如果您使用newInstance,那么您必须保证它已关闭以避免泄漏并产生长期影响。

3.您可以通过编辑core-site.xml并将属性fs。<文件系统类型> .impl.disable.cache设置为true来禁用特定文件系统类型的FileSystem缓存,例如fs.hdfs.impl.disable.cache。通常,禁用缓存是不可取的,因为缓存的性能优势是显而易见的。有时这对于特定应用程序来说是一种有用的解决方法。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值