相关背景:
hbase集群大量regionserver节点进程挂掉,排查log发现每个节点上的有大量的和datanode建立连接失败的报错信息,进一步排查是大量的Too Many Open Files异常导致的,所以挂掉的原因是Linux服务器上的File Descriptor数量不足,无法新建socket连接去读写datanode数据导致进程退出。每台服务器上处于CLOSE_WAIT状态的tcp连接有10万+,基本都是regionserver访问datanode产生的大量tcp连接;简单回顾一下TCP断开连接的过程,主动方发送FIN包请求关闭连接,被动关闭的一方响应并发出 ACK 包之后就进入了 CLOSE_WAIT 状态。如果一切正常,稍后被动关闭的一方也会发出 FIN 包,然后迁移到 LAST_ACK 状态。因此,CLOSE_WAIT产生的原因是被动关闭的一方收到FIN请求后没有发送FIN包,也就是没有执行close方法;
对应到当前问题,regionserver大量访问Datanode服务进程,Datanode端已经由于某种原因(超时等)主动关闭了socket连接,但是regionserver端没有调用close去释放当前的socket连接。
所以解决的问题就是regionserver关闭与datanode的socket连接的问题;参考hadoop和hbase社区已经有了相关的解决方案,大概思路是regonserver端在访问hdfs数据后调用hdfs接口释放掉无用socket连接;
https://issues.apache.org/jira/browse/HBASE-9393(Region Server fails to properly close socket resulting in many CLOSE_WAIT to Data Nodes)https://issues.apache.org/jira/browse/HDFS-7694(FSDataInputStream should support "unbuffer")
CLOSE_WAIT
CLOSE_WAIT 是TCP关闭连接过程中的一个正常状态,通常情况下,CLOSE_WAIT 状态维持时间很短,如果你发现TCP连接长时间的处于CLOSE_WAIT 状态,那么就意味着被动关闭的一方没有及时发出 FIN 包,说明代码层面存在一定的问题