HDFS配额总结
标签(空格分隔): Apache Hadoop
HDFS允许管理员给私人目录设置其下面文件夹和文件的总数量配额,或空间使用总量配额。所以HDFS配额的对象是目录,而非用户。如果需要实现用户级别的配额,则需要采用第三方系统进行逻辑管理并映射到文件夹配额。
在往有配额的目录中写数据时,如果超过限额,会提示DSQuotaExceededException异常,所以提早提醒文件夹所属的用户非常有意义。
一,文件数配额(Name Quota)
文件数配额指的是可以限制当前文件夹下,所有文件和文件夹的总数量(包含所有的文件夹和文件inode).类似于linux系统中ulimit里的hard limit。
二,空间配额(Space Quota)
- 空间配额指的是可以限制当前文件夹下,所有文件(包含子文件夹中的数据文件,会递归的去统计)的总大小,设置值包含副本因素,即N=fileSize * Replication。
- 文件数配合空间配额可以同时使用,并不冲突。同时测试发现空间配额会有384MB物理空间(128MB逻辑空间,默认数据块大小)的固定预留,就是说当空间配额还剩下384MB时候,写文件就会失败
设置空间配额:
dfsadmin -setSpaceQuota <N> <directory>...<directory>
给每个目录设置空间配额为N Byte,N可以是5g或者2t。空间配额表示这个文件夹下所有文件的总大小,包含副本因素,即N=fileSize * Replication。
清除空间配额:
dfsadmin -clrSpaceQuota <directory>...<directory>
- 清除各个目录的空间配额。实际上是把空间配额设置为0。
- 设置配额必须由管理员来进行。
三,物理空间与逻辑空间
物理空间:文件实际占用HDFS的大小,包含副本因素,等于逻辑空间*副本数。
逻辑空间:文件本身大小,du命令显示的结果。
hdfs fsck和 hadoop fs -count 出来的CONTENT_SIZE指的都是逻辑空间,而物理空间是逻辑空间每个文件本身的副本数,如果replication是3,则REMAINING_SPACE_QUOTA的计算公式为:
`REMAINING_SPACE_QUOTA=SPACE_QUOTA - CONTENT_SIZE 3`
因此,空间配额限制的是物理空间,假设设置了一个文件夹的空间配额为3GB,副本数为3,那么最多可以存放总大小1GB的文件。
四,Storage Type Quota
在2.7版本中,可以指定一个文件夹中的Storage Type是RAM_DISK/SSD/DISK/ARCHIVE。
也就是 HDFS 提供的 异构存储。
五,通过shell显示quota
显示Quota:
hadoop fs -count -q -h /tmp/testquota /tmp/testquota2
实际上是调用了fs.getContentSummary()方法,得到当前目录的ContencSummary信息。
结果输出:
10 8 none inf 1 1 0 /tmp/testquata
none inf 419430400 331751851 1 1 29226183 /tmp/testquata2
各列的含义:
/**
* Output format:
* <----12----> <----15----> <----15----> <----15----> <----12----> <----12----> <-------18------->
* QUOTA REMAINING_QUATA SPACE_QUOTA SPACE_QUOTA_REM DIR_COUNT FILE_COUNT CONTENT_SIZE FILE_NAME
*/
QUOTA:文件数配额,(如果没有配额,则显示为none,空间配额同理)
=quota
REMAINING_QUATA:剩余的文件数配额(剩余能创建的目录和文件数量)
=quota-fileCount-dirCount(如果没有配额,则显示为inf)
SPACE_QUOTA:空间配额(限制磁盘占用大小)
=spaceQuota
SPACE_QUOTA_REM:剩余可以用的磁盘空间
=spaceQuota-spaceConsumed
FILE_COUNT/FILE_COUNT:文件/目录数
CONTENT_SIZE:逻辑空间大小,不计副本因素
=每个文件/文件的spaceConsumed/其replication
六,通过编程设置和显示Quota
可以通过DistributedFileSystem.set/getQuota()等一系列方法来设置Quota,在2.7版本中,可以分别设置namespace和storagespace的Quota,还可以StorageType Quota。
写文件超出限额具体的异常信息:
20/03/18 16:55:27 WARN hdfs.DFSClient: DataStreamer Exception
org.apache.hadoop.hdfs.protocol.DSQuotaExceededException: The DiskSpace quota of /tmp/testquata2 is exceeded: quota = 41943040 B = 40 MB but diskspace consumed = 402653184 B = 384 MB
at org.apache.hadoop.hdfs.server.namenode.INodeDirectoryWithQuota.verifyQuota(INodeDirectoryWithQuota.java:195)
at org.apache.hadoop.hdfs.server.namenode.FSDirectory.verifyQuota(FSDirectory.java:2111)
at org.apache.hadoop.hdfs.server.namenode.FSDirectory.updateCount(FSDirectory.java:1845)
at org.apache.hadoop.hdfs.server.namenode.FSDirectory.updateCount(FSDirectory.java:1820)
at org.apache.hadoop.hdfs.server.namenode.FSDirectory.addBlock(FSDirectory.java:373)
at org.apache.hadoop.hdfs.server.namenode.FSNamesystem.saveAllocatedBlock(FSNamesystem.java:2965)
at org.apache.hadoop.hdfs.server.namenode.FSNamesystem.getAdditionalBlock(FSNamesystem.java:2636)
at org.apache.hadoop.hdfs.server.namenode.NameNodeRpcServer.addBlock(NameNodeRpcServer.java:563)
at org.apache.hadoop.hdfs.protocolPB.ClientNamenodeProtocolServerSideTranslatorPB.addBlock(ClientNamenodeProtocolServerSideTranslatorPB.java:407)
at org.apache.hadoop.hdfs.protocol.proto.ClientNamenodeProtocolProtos$ClientNamenodeProtocol$2.callBlockingMethod(ClientNamenodeProtocolProtos.java)
at org.apache.hadoop.ipc.ProtobufRpcEngine$Server$ProtoBufRpcInvoker.call(ProtobufRpcEngine.java:585)
at org.apache.hadoop.ipc.RPC$Server.call(RPC.java:928)
at org.apache.hadoop.ipc.Server$Handler$1.run(Server.java:1962)
at org.apache.hadoop.ipc.Server$Handler$1.run(Server.java:1)
at java.security.AccessController.doPrivileged(Native Method)
at javax.security.auth.Subject.doAs(Subject.java:415)
at org.apache.hadoop.security.UserGroupInformation.doAs(UserGroupInformation.java:1548)
at org.apache.hadoop.ipc.Server$Handler.run(Server.java:1957)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:526)
at org.apache.hadoop.ipc.RemoteException.instantiateException(RemoteException.java:106)
at org.apache.hadoop.ipc.RemoteException.unwrapRemoteException(RemoteException.java:73)
at org.apache.hadoop.hdfs.DFSOutputStream$DataStreamer.locateFollowingBlock(DFSOutputStream.java:1267)
at org.apache.hadoop.hdfs.DFSOutputStream$DataStreamer.nextBlockOutputStream(DFSOutputStream.java:1112)
at org.apache.hadoop.hdfs.DFSOutputStream$DataStreamer.run(DFSOutputStream.java:522)
Caused by: org.apache.hadoop.ipc.RemoteException(org.apache.hadoop.hdfs.protocol.DSQuotaExceededException): The DiskSpace quota of /tmp/testquata2 is exceeded: quota = 41943040 B = 40 MB but diskspace consumed = 402653184 B = 384 MB
at org.apache.hadoop.hdfs.server.namenode.INodeDirectoryWithQuota.verifyQuota(INodeDirectoryWithQuota.java:195)
at org.apache.hadoop.hdfs.server.namenode.FSDirectory.verifyQuota(FSDirectory.java:2111)
at org.apache.hadoop.hdfs.server.namenode.FSDirectory.updateCount(FSDirectory.java:1845)
at org.apache.hadoop.hdfs.server.namenode.FSDirectory.updateCount(FSDirectory.java:1820)
at org.apache.hadoop.hdfs.server.namenode.FSDirectory.addBlock(FSDirectory.java:373)
at org.apache.hadoop.hdfs.server.namenode.FSNamesystem.saveAllocatedBlock(FSNamesystem.java:2965)
at org.apache.hadoop.hdfs.server.namenode.FSNamesystem.getAdditionalBlock(FSNamesystem.java:2636)
at org.apache.hadoop.hdfs.server.namenode.NameNodeRpcServer.addBlock(NameNodeRpcServer.java:563)
at org.apache.hadoop.hdfs.protocolPB.ClientNamenodeProtocolServerSideTranslatorPB.addBlock(ClientNamenodeProtocolServerSideTranslatorPB.java:407)
at org.apache.hadoop.hdfs.protocol.proto.ClientNamenodeProtocolProtos$ClientNamenodeProtocol$2.callBlockingMethod(ClientNamenodeProtocolProtos.java)
at org.apache.hadoop.ipc.ProtobufRpcEngine$Server$ProtoBufRpcInvoker.call(ProtobufRpcEngine.java:585)
at org.apache.hadoop.ipc.RPC$Server.call(RPC.java:928)
at org.apache.hadoop.ipc.Server$Handler$1.run(Server.java:1962)
at org.apache.hadoop.ipc.Server$Handler$1.run(Server.java:1)
at java.security.AccessController.doPrivileged(Native Method)
at javax.security.auth.Subject.doAs(Subject.java:415)
at org.apache.hadoop.security.UserGroupInformation.doAs(UserGroupInformation.java:1548)
at org.apache.hadoop.ipc.Server$Handler.run(Server.java:1957)
at org.apache.hadoop.ipc.Client.call(Client.java:1406)
at org.apache.hadoop.ipc.Client.call(Client.java:1359)
at org.apache.hadoop.ipc.ProtobufRpcEngine$Invoker.invoke(ProtobufRpcEngine.java:206)
at com.sun.proxy.$Proxy9.addBlock(Unknown Source)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.apache.hadoop.io.retry.RetryInvocationHandler.invokeMethod(RetryInvocationHandler.java:186)
at org.apache.hadoop.io.retry.RetryInvocationHandler.invoke(RetryInvocationHandler.java:102)
at com.sun.proxy.$Proxy9.addBlock(Unknown Source)
at org.apache.hadoop.hdfs.protocolPB.ClientNamenodeProtocolTranslatorPB.addBlock(ClientNamenodeProtocolTranslatorPB.java:348)
at org.apache.hadoop.hdfs.DFSOutputStream$DataStreamer.locateFollowingBlock(DFSOutputStream.java:1264)
... 2 more
put: The DiskSpace quota of /tmp/testquata2 is exceeded: quota = 41943040 B = 40 MB but diskspace consumed = 402653184 B = 384 MB