From 5e0807743b1cbf27e5401e0a00cc549076c4f1f5 Mon Sep 17 00:00:00 2001 From: zeekling Date: Sun, 31 Mar 2024 20:48:14 +0800 Subject: [PATCH 1/5] =?UTF-8?q?FSDirectory=E8=AF=A6=E8=A7=A3:=E9=85=8D?= =?UTF-8?q?=E7=BD=AE=E5=92=8C=E5=8F=98=E9=87=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- hdfs/FSDirectory详解.md | 44 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 hdfs/FSDirectory详解.md diff --git a/hdfs/FSDirectory详解.md b/hdfs/FSDirectory详解.md new file mode 100644 index 0000000..381b495 --- /dev/null +++ b/hdfs/FSDirectory详解.md @@ -0,0 +1,44 @@ + +## 简介 + +Namenode最重要的两个功能之一就是维护整个文件系统的目录树(即命名空间namesystem) 。 +HDFS文件系统的命名空间(namespace) , 也就是以“/”为根的整个目录树, 是通过FSDirectory类来管理的。 FSNamesystem也提供了管理目录树结构的方法。 +FSNamesystem中的方法多是调用FSDirectory类的实现。FSNamesystem在FSDirectory类方法的基础上添加了editlog日志记录的功能。 + +FSDirectory的操作则全部是在内存中进行的, 并不进行editlog的日志记录。 + +## 参数 + +| 参数 | 默认值 | 描述 | +|----|----|----| +| dfs.permissions.enabled | true | 是否开启权限管理 | +| dfs.permissions.superusergroup | supergroup | 超级用户组 | +| dfs.namenode.acls.enabled | true | 设置为true以启用对HDFS ACL(访问控制列表)的支持。3.3.1版本默认启用ACL | +| dfs.namenode.posix.acl.inheritance.enabled | true | 是否启用POSIX格式的ACL权限 | +| dfs.namenode.xattrs.enabled | true | 是否支持扩展namenode的属性。 | +| dfs.namenode.fs-limits.max-xattr-size | 16384 | 以字节为单位的扩展属性的名称和值的最大组合大小。它应该大于0,小于或等于32768。 | +| dfs.namenode.accesstime.precision | 3600000 | HDFS文件访问时间的精确值,默认为1小时。当为0时,表示禁用。 | +| dfs.quota.by.storage.type.enabled | true | 如果为true,则启用基于存储类型的配额。 | +| dfs.ls.limit | 1000 | 限制ls打印的文件数。如果小于或等于零,最多将打印 DFS_LIST_LIMIT_DEFAULT (= 1000)。 | +| dfs.content-summary.limit | 5000 | 在一个锁定周期中允许的最大内容摘要计数。0或负数意味着没有限制。 | +| dfs.content-summary.sleep-microsec | 500 | 在内容汇总计算中,两次请求锁的时间。 | +| dfs.namenode.fs-limits.max-component-length | 255 | 定义路径中每个组件中UTF-8编码的最大字节数。0的值将禁用检查。 | +| dfs.namenode.fs-limits.max-directory-items | 1024\*1024 | 定义目录可能包含的最大项目数。无法将属性设置为小于1或大于6400000的值。| +| dfs.namenode.fs-limits.max-xattrs-per-inode | 32 | 每个索引节点的扩展属性的最大数目。 | +| dfs.protected.subdirectories.enable | false | 是否保护 fs.protected.directories 上设置的目录的子目录。 | +| dfs.namenode.name.cache.threshold | 10 | 经常访问的文件访问次数超过了这个阈值,缓存在FSDirectory nameCache中。 | +| dfs.namenode.quota.init-threads | 12 | quota初始化并发线程的数量。 | + + +## 常量 + +- INodeDirectory rootDir: 整个文件系统目录树的根节点, 是INodeDirectory类型的 。 +- FSNamesystem namesystem: Namenode的门面类, 这个类主要支持对数据块进行操作的一些方法, 例如addBlock()。 +- INodeMap inodeMap: 记录根目录下所有的INode,并维护INodeId ->INode的映射关系。 +- ReentrantReadWriteLock dirLock: 对目录树以及inodeMap字段操作的锁。 +- NameCache nameCache: 将常用的name缓存下来, 以降低byte[]的使用, 并降低JVM heap的使用。 + + + + + -- 2.45.2 From 6504a13b23d2166c9060159c7b174a899cca5648 Mon Sep 17 00:00:00 2001 From: zeekling Date: Sun, 31 Mar 2024 21:34:54 +0800 Subject: [PATCH 2/5] =?UTF-8?q?FSDirectory=E8=AF=A6=E8=A7=A3:=E9=85=8D?= =?UTF-8?q?=E7=BD=AE=E5=92=8C=E5=8F=98=E9=87=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- hdfs/FSDirectory详解.md | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/hdfs/FSDirectory详解.md b/hdfs/FSDirectory详解.md index 381b495..cddf6e2 100644 --- a/hdfs/FSDirectory详解.md +++ b/hdfs/FSDirectory详解.md @@ -33,12 +33,13 @@ FSDirectory的操作则全部是在内存中进行的, 并不进行editlog的 ## 常量 - INodeDirectory rootDir: 整个文件系统目录树的根节点, 是INodeDirectory类型的 。 -- FSNamesystem namesystem: Namenode的门面类, 这个类主要支持对数据块进行操作的一些方法, 例如addBlock()。 -- INodeMap inodeMap: 记录根目录下所有的INode,并维护INodeId ->INode的映射关系。 -- ReentrantReadWriteLock dirLock: 对目录树以及inodeMap字段操作的锁。 -- NameCache nameCache: 将常用的name缓存下来, 以降低byte[]的使用, 并降低JVM heap的使用。 - - - +- FSNamesystem namesystem: Namenode的门面类, 这个类主要支持对数据块进行操作的一些方法, 例如addBlock()。 +- INodeMap inodeMap: 记录根目录下所有的INode,并维护INodeId ->INode的映射关系。 +- ReentrantReadWriteLock dirLock: 对目录树以及inodeMap字段操作的锁。 +- NameCache nameCache: 将常用的name缓存下来, 以降低byte[]的使用, 并降低JVM heap的使用。 +- SortedSet protectedDirectories:使用 dfs.namenode.protected.directories 设置保护的一组目录。 这些目录不能被删除,除非它们是空的。 +- FSEditLog editLog: 用于写editlog的类。 +- HdfsFileStatus[] reservedStatuses: 待定。 +- INodeAttributeProvider attributeProvider:用于实现权限管理。 -- 2.45.2 From a2aff039dbf2f64b7064ce55a2a716a26d33ca7c Mon Sep 17 00:00:00 2001 From: zeekling Date: Sat, 6 Apr 2024 23:18:46 +0800 Subject: [PATCH 3/5] =?UTF-8?q?FSDirectory=E8=AF=A6=E8=A7=A3:=E9=85=8D?= =?UTF-8?q?=E7=BD=AE=E5=92=8C=E5=8F=98=E9=87=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- hdfs/FSDirectory详解.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/hdfs/FSDirectory详解.md b/hdfs/FSDirectory详解.md index cddf6e2..246b813 100644 --- a/hdfs/FSDirectory详解.md +++ b/hdfs/FSDirectory详解.md @@ -43,3 +43,17 @@ FSDirectory的操作则全部是在内存中进行的, 并不进行editlog的 - INodeAttributeProvider attributeProvider:用于实现权限管理。 +## 操作类型 + +所有客户端的操作都是通过FSNamesystem.java 的。FSNamesystem.java 会调用具体操作的实现类的。再实现类里面操作时会使用到FSDirectory。 + +### 删除 + +接口: + +```java +boolean delete(String src, boolean recursive, boolean logRetryCache) throws IOException {} +``` + + + -- 2.45.2 From b83b0dcf0400868a50e6297fc13a2245ab7922ba Mon Sep 17 00:00:00 2001 From: zeekling Date: Mon, 8 Apr 2024 23:57:38 +0800 Subject: [PATCH 4/5] =?UTF-8?q?FSDirectory=E8=AF=A6=E8=A7=A3:=E9=85=8D?= =?UTF-8?q?=E7=BD=AE=E5=92=8C=E5=8F=98=E9=87=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- hdfs/FSDirectory详解.md | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/hdfs/FSDirectory详解.md b/hdfs/FSDirectory详解.md index 246b813..6627c62 100644 --- a/hdfs/FSDirectory详解.md +++ b/hdfs/FSDirectory详解.md @@ -49,11 +49,29 @@ FSDirectory的操作则全部是在内存中进行的, 并不进行editlog的 ### 删除 -接口: +**接口**: ```java boolean delete(String src, boolean recursive, boolean logRetryCache) throws IOException {} ``` +**简介** + +删除文件或者文件夹,如果删除文件夹参数recursive必须为true。 + +**实现逻辑** + +- 1、检查是否有写权限。具体可查看`checkOperation(OperationCategory.WRITE)`; +- 2、加全局锁。 +- 3、再次检查是否有写权限。 +- 4、调用FSDirDeleteOp.delete删除目录或者文件。 + ```java + toRemovedBlocks = FSDirDeleteOp.delete(this, pc, src, recursive, logRetryCache); + ``` +- 5、释放全局锁。 +- 6、同步editlog,并且记录审计日志。 +- 7、将需要删除的块`toRemovedBlocks`添加到`markedDeleteQueue`队列里面,等待异步删除。 + +**FSDirDeleteOp.delete 实现逻辑** -- 2.45.2 From fe069fcf71cb437c00520fe384214d831e1184d7 Mon Sep 17 00:00:00 2001 From: zeekling Date: Sat, 13 Apr 2024 22:08:29 +0800 Subject: [PATCH 5/5] =?UTF-8?q?FSDirectory=E8=AF=A6=E8=A7=A3:=E9=85=8D?= =?UTF-8?q?=E7=BD=AE=E5=92=8C=E5=8F=98=E9=87=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- hdfs/FSDirectory详解.md | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/hdfs/FSDirectory详解.md b/hdfs/FSDirectory详解.md index 6627c62..f931704 100644 --- a/hdfs/FSDirectory详解.md +++ b/hdfs/FSDirectory详解.md @@ -74,4 +74,25 @@ boolean delete(String src, boolean recursive, boolean logRetryCache) throws IOEx **FSDirDeleteOp.delete 实现逻辑** +- 检查权限:调用FSDirectory的函数checkPermission检查权限。 +- 如果是非空的文件夹,检查是否有-r参数。如果没有-r参数则需要报错。 +- 调用deleteInternal,开始删除文件夹。核心删除代码如下: + +```java +List snapshottableDirs = new ArrayList<>(); +FSDirSnapshotOp.checkSnapshot(fsd, iip, snapshottableDirs); +ReclaimContext context = new ReclaimContext( + fsd.getBlockStoragePolicySuite(), collectedBlocks, removedINodes, + removedUCFiles); +// 更核心的删除代码再这个函数里面,会调用destroyAndCollectBlocks删除block,代码:targetNode.destroyAndCollectBlocks(reclaimContext); +if (unprotectedDelete(fsd, iip, context, mtime)) { + filesRemoved = context.quotaDelta().getNsDelta(); + fsn.removeSnapshottableDirs(snapshottableDirs); +} +fsd.updateReplicationFactor(context.collectedBlocks() + .toUpdateReplicationInfo()); +fsd.updateCount(iip, context.quotaDelta(), false); +``` +- 删除EditLog。 +- 调用incrDeletedFileCount更新metrics信息。 -- 2.45.2