HDFS——配额

Posted hncscwc

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HDFS——配额相关的知识,希望对你有一定的参考价值。

【配额】


HDFS中,配额用于限制目录的使用空间,具体可分为名称配额空间配额


空间配额指的是单个目录中所有文件总的大小限制,文件副本的大小也计算在内。

名称配额指的是根目录树中的文件和目录的最大数量,即递归计算子目录,孙子目录下的文件和目录数。


通过如下命令可以对具体目录设置其配额:

# 设置名称配额# max_number 为最大文件/目录数# dirname 为指定的目录hdfs dfsadmin -setQuota <max_number> <dirname># 设置空间配额# bytes 为最大存储字节数hdfs dfsadmin -setSpaceQuota <bytes> <dirname>


通过如下命令可以查看目录的配额情况:

hdfs dfs -count -q /tmp/hncscwc# 显示结果    # 名称配额大小  名称配额剩余大小  空间配额大小  空间配额剩余大小  目录数  文件数  文件大小 目录的路径   none  inf  536870912  536870912  1  0  0  /tmp/hncscwc


通过如下命令可以清除配额:

# 清除名称配额hdfs dfsadmin -clrQuota <dirname># 清除空间配额额hdfs dfsadmin -clrSpaceQuota <dirname>



【内部实现】



  • 配额在内存中的保存

    配额在内存中是跟随目录信息一并存储的。


    在NN的内部实现中,INodeDirectory类记录目录的相关信息,每个目录都有一个具体的实例对象,该类继承自抽象类INodeWithAdditionalFields,在父类中有一个features的成员变量,保存了该inode上的所有特性,包括ACL,配额,快照,附加属性等等。其中配额属性就记录了该inode的空间配额,名称配额以及当前的使用情况。

    具体数据结构如下图所示:


  • 配额的持久化保存

    设置的配额信息最后会作为一个操作持久化到editlog中,具体记录目录的路径、对应的空间配额、名称配额。


    随着checkpoint的执行,editlog中的操作信息最终会记录到fsiamge中保存。


  • 配额的使用

    NN在处理创建文件、目录、或者写新的文件,append已有的文件等请求时,会进行对应目录配额的校验判断(包括当前目录的配额,逐级往上父目录的配额,祖父目录的配额等),如果未超过设置的配额,则允许其操作,并在内存中更新当前目录的使用情况。


【能否针对用户进行配额的设置】



在HDFS中有用户、用户组的概念,即每个文件/目录属于指定用户、用户组。同时可以通过开启ACL,为文件/目录设置访问权限。这样HDFS也就支持多用户了。


在多用户的真实场景中,通常是以用户为单位来设置配额,即某个用户能使用多大的空间。对照HDFS的配额,可能就需要指定某个用户能写哪些目录,然后为这些目录分别设置配额,来实现用户配额的功能。


那么,HDFS能否支持直接按照用户来进行配额呢?或者说,如果要支持按照用户来进行配额,HDFS需要做哪些改动呢?


首先要考虑到的就是,用户的配额信息需要进行持久化的存储,因此需要添加对应的editlog操作,同时fsiamge中也需要进行对应的存储(即改变fsiamge的存储信息),然后每个文件进行写操作,文件拷贝,快照等操作时,需要判断是否超过用户的配额。此外在联邦的场景中,考虑的情况会更复杂。


到目前为止,官方的版本中是不支持对用户进行配额的设置的


在社区中,看到有类似的问题讨论,但没有实际结论或计划进行相应的设计开发。

(详见HDFS-8575:https://issues.apache.org/jira/browse/HDFS-8575)


【FAQ】



  • 对某个目录设置了配额,如果将该目录改名会怎样?

    从上面的内部实现中可以知道,配额是目录属性的一部分,通过mv将目录改名,在HDFS中,该目录对应的inode没有变化,因此配额信息仍旧是跟随该目录一起的。


    hdfs dfsadmin -setSpaceQuota 536870912 /tmp/hncscwchdfs dfs -count -q /tmp/hncscwc    none  inf  536870912  536870912  1  0  0  /tmp/hncscwchdfs dfs -mv /tmp/hncscwc /tmp/spurshdfs dfs -count -q /tmp/hncscwc none inf 536870912 536870912 1 0 0 /tmp/spurs


  • 子目录的配额能否大于父目录的配额?

    子目录的配额可以大于父目录的配额,也就是说,HDFS的实现中,设置配额时,并没有逐级往上去判断父目录的配额情况。


    但是,在真正进行文件存储的时候,就会逐级往上判断是否超过父目录,祖父目录等的配额,如果超过则写入失败。


    hdfs dfs -count -q /tmp/hncscwc /tmp/hncscwc/hadoop  none  inf   536870912   536870912  2  0  0  /tmp/hncscwc  none  inf  1073741824  1073741824  1  0  0  /tmp/hncscwc/hadoop


  • 如果查看当前目录已使用的空间?

    通过"dfs -count"可以看到具体目录的配额和已经剩余空间,这样可以推断出实际的使用空间。但是对于未设置配额的目录,配额显示为none,剩余空间显示为inf,这样就无法推断出目录实际的使用空间。


    查看源码发现,可以通过客户端的getQuotaUsage接口获取到具体目录的配额与实际已使用空间大小。


    实际上,"dfs -count"命令也就是调用了该接口拿到相关信息,只是增加了判断,如果配额为空,则不进行剩余空间的计算。


【总结】



本文简单总结了HDFS配额相关的原理,欢迎指正交流。



以上是关于HDFS——配额的主要内容,如果未能解决你的问题,请参考以下文章

HDFS配额指南

HDFS——配额

hdfs配额查询

HDFS配额查询

HDFS 配额(Quotas)指南 -- Apache Hadoop 2.9.0

如何使用Java API访问HDFS为目录设置配额