HDFS新运维工具命令之listOpenFiles命令
前言
在运维集群的时候,我们有的时候需要去知道哪些文件存在未被及时关闭的情况。否则会造成一定程度上的资源泄露,比如内存无缘无故就被耗掉了。可能有人会想,好端端的文件,为什么会存在未被关闭的情况呢?答案是有可能的,当发生各种异常写文件的情况时,就有可能发生。这在HDFS内部同样也会发生。对此,社区最近在实现添加一项新的管理员命令-listOpenFiles命令来帮助集群管理者获取这些“打开中的文件”,此命令可以即时获取当前集群中有哪些文件是处于打开中的状态。本文笔者打算谈谈此命令另外一些辅助的用处。此命令在其它场景同样有重要的作用。
listOpenFiles的应用场景
listOpenFiles命令有以下主要几大使用场景
1)调试,定位问题时进行使用。
2)关闭异常情况导致资源泄露的文件。
3)找到那些阻塞住节点下线的未关闭的文件。
前面2点,大家一看就明白了,笔者这里主要谈一谈第3点,什么叫“那些阻塞住节点下线的未关闭的文件”?这得要提及一些HDFS中节点做decomission下线操作的内容了。在DataNode节点下线中,有这么一条需要满足的要求:当待下线节点中存在打开中的文件,表明此文件目前不是一个完整状态,此文件副本就无法复制到其它节点上,由于存在未完全复制完的副本,则待下线节点就无法被下线。也就是前面说的阻塞住下线操作了。当集群规模达到千级别,万级别规模时,节点变更操作是非常频繁的,如果出现文件未关闭导致节点无法下线,将会是一件麻烦的事,所以listOpenFiles在这种情况下是非常有帮助的。
现有类似命令:hdfs fsck -openforwrite
在现有的hdfs子命令中,也的确存在类似功能的命令:fsck -openforwrite,通过此命令,我们也能得到打开中的文件信息。但是此命令最大的不同在于它是一个开销比较大的命令,它会持有整个文件系统,而且当扫描比较大的父目录时,扫描时间会比较长,用过fsck命令的同学可能会深有体会。而新添加的listOpenFiles命令所实现的方式则完全不同,首先它的构造目标就是一个轻量级的命令。下面我们来看listOpenFiles的实现原理。
新命令实现:dfsadmin -listOpenFiles
listOpenFiles新命令是计划实现在dfsadmin管理员命令下。要实现此命令,很关键的一个问题需要我们去了解:如何知道集群中有哪些文件是处于打开中准备被写的状态呢?这个我们得从租约管理器(LeaseManager)中去找答案。我们知道,客户端每次要向HDFS内写文件的时候,是需要对此文件新建一个lease(租约)的,表明当前文件由某个客户端正在被写,其它客户端此时是不允许写入相同文件的。所以在租约管理器中,会对应下面这样一层关系:
lease holder(租约持有客户端)--->lease(租约)----->单一/多个文件集合
租约管理器内部对上面这层关系进行了灵活的映射构造,我们可以拿到文件-->租约这样的逆向关系。然后在LeaseManager类中实现对外方法接口,从DFSAdmin类里传入命令参数,触发NameNode的调用,进而调用LeaseManager中的方法。此处具体代码实现可阅读相关JIRA:HDFS-10480(Add an admin command to list currently open files)。
listOpenFiles命令的本地测试输出结果如下,在输出结果中包括,客户端持有者名称,客户端所在节点以及打开中的文件。
Client Host Client Name Open File Path
127.0.0.1 DFSClient_NONMAPREDUCE_702519585_203 /tmp/files/open-file-0
127.0.0.1 DFSClient_NONMAPREDUCE_702519585_203 /tmp/files/open-file-1
127.0.0.1 DFSClient_NONMAPREDUCE_702519585_203 /tmp/files/open-file-2
127.0.0.1 DFSClient_NONMAPREDUCE_702519585_203 /tmp/files/open-file-3
127.0.0.1 DFSClient_NONMAPREDUCE_702519585_203 /tmp/files/open-file-4
127.0.0.1 DFSClient_NONMAPREDUCE_702519585_203 /tmp/files/open-file-5
127.0.0.1 DFSClient_NONMAPREDUCE_702519585_203 /tmp/files/open-file-6
127.0.0.1 DFSClient_NONMAPREDUCE_702519585_203 /tmp/files/open-file-7
127.0.0.1 DFSClient_NONMAPREDUCE_702519585_203 /tmp/files/open-file-8
127.0.0.1 DFSClient_NONMAPREDUCE_702519585_203 /tmp/files/open-file-9
listOpenFiles命令后续的优化
目前在HDFS-10480中命令实现的部分只是实现了一个最基本的部分,其实还存在2个优化点:
1)能够以节点作为过滤条件,筛选出只隶属于输入节点下的打开文件,能够帮助我们直接的发现目标文件。这部分内容将在HDFS-11847中给予实现。
2)能够以给定路径作为过滤条件,因为有时我们并需要得到集群中所有打开的文件,它可能会非常多。这部分内容将在HDFS-11848中给予实现。
感兴趣的同学后续可以持续关注这2个issue。
参考资料
[1].Add an admin command to list currently open, https://issues.apache.org/jira/browse/HDFS-10480.
[2].Enhance dfsadmin listOpenFiles command to list files blocking datanode datanode decommissioning, https://issues.apache.org/jira/browse/HDFS-11847.
[3].Enhance dfsadmin listOpenFiles command to list files under a given path, https://issues.apache.org/jira/browse/HDFS-11848.