Hadoop 客户端长期运行造成Datanode 连接泄露, 0.21.0 仍然存在这问题

上篇文章中说到我在Hadoop的50070的web页面增加了每个node的xceiver count,这个问题也是通过这个指标发现的。

由于我的客户端从始至终都是一个Filesystem实例,因此在put完文件时java实例并不会销毁,客户端在运行较长时间后,发现每个Node的xceiver count值很高,当初以为是节点读写量比较大,但通过stack分析来看,却是写的线程比较多,难道又是当初的老毛病 http://dongyajun.iteye.com/blog/628028

除非数据无法flush到datanode,会造成客户端无法关闭流外(DFSClient#flushInternal方法中的长久wait),其他情况都会关闭流并关闭socket,昨天在阅读代码时,偶然想到了,对于一个超过block大小的文件,客户端会申请多个block,并会向datanode建立多次连接,然而都是用的同一个Socket引用(DFSOutputStream#s:Socket),在给这个socket重赋值时,并未关闭这个socket,长期以来,客户端会积累大量对datanode的连接,当你销毁客户端实例时,你会看到datanode的Xceiver Count也随之下降了 

发现这个问题之后的第一件事是阅读最新的hadoop源码,发现仍然未有close socket的迹象,在确定确实存在这个问题后,在createBlockOutputStream方法中,当socket重新赋值时,关闭socket.
IOUtils.closeSocket(s);
s = socketFactory.createSocket();


该问题也向@luoli523 询问过,他们也曾在hbase中遇到这样的问题,如果大家也遇到此问题,不防试试,不过… Hadoop的开发者们难道会出这样的低级错误?

你可能感兴趣的:(多线程,Web,hadoop,socket,hbase)