老师好,小义同学,这是大厂面试拆解——项目实战系列的第8篇文章。

知识地图:深入理解计算机系统—文件子系统

一次只讲清楚一个问题:

阅读本文你将获得以下收益:

  • ✅ ext4文件系统为了支持单个文件最大16TB存储,采用哪些数据结构?
  • ✅ 文件在创建、打开、读取过程中与上述数据结构有什么关系?(分析中)

“走暗路、耕瘦田、进窄门、见微光"告诉我,面试关键就在于深入理解自己的项目,这才是最考察基本功的地方。然而现实情况往往是这样的:

  1. 第一家公司A:面试官问同样一个项目问题,没有回答出来,直接拜拜。
  2. 公司A没有复盘明白,换下一家公司B面试,还是面试同样问题,还是回答不出来,直接拜拜。
  3. 第三个公司C继续去面试,同样问题回答不出来,直接拜拜。
  4. 过几年再去面试,还是面试同样问题。

为什么会这样?

  1. 对同一个行业来说,面临都是相同业务场景,采用相同技术方案,差别就在于深入理解。有的企业通过添加机器解决,有的企业引用开源软件解决,有的企业需要定制开发。差距一个天上,一个地下。因为这些问题面试官根据业务挑选出来的题目,同一个题目卡住上千人、上万人,面试官不需要换题目。因为这就是行业最难挑战。仅仅看书,仅仅背诵八股文无法解决。

  2. 你10+年工作经验的程序员,面试官至少P6、P7标准考察。企业需要什么人才?面试官只出一个项目题目,一个算法题目,就彻底考察一个候选人。必须超预期回答,不能像刚毕业那样回答,只沉浸在当时项目中。当时项目一钱不值,面试目的不是一个人写一个功能,而是一个人挑战整个行业。你要说自己可以,我行,在基础知识方面你做到最强。

  3. 工作10年,面试官招聘的是一个人独立负责一个特性,给公司解决问题的,而不是什么设计好,按部就班。那个实习生、应届生,我已经没有这样待遇了。考察的是过去积累,而不是仅仅岗位。

答疑1:通过提供数据结构来数据EXT4文件系统

ext4文件系统为了支持单个文件最大16TB存储,采用哪些数据结构?可视化的逻辑结构和代码实现怎么对应的?

这里假设你熟悉了

  1. 了解严老师写的<数据结构>(C语言版)逻辑结构(不用紧张,非代码实现),参考一下 通过动画可视化数据结构和算法。
  2. **了解文件系统基本组成部分- 目录项,索引节点,逻辑块,,超级块 逻辑结构简单理解 小提示:为什么非要打破砂锅问到底(这个提示有点长)
  3. 在日常生活中,通过网络搜集搜集到资料, 感觉有问题但是描述不出来,这就是 实践最好时机,现在要做事情把模糊感觉变成一个具体问题,如果无法变成具体问题,根本无法作者交流,只会点赞收藏,这个毫无意义,后面忙碌工作就淡忘。这给自己抱怨,不是我不想学,被安排太多事情,哪怕后面有时间也不会看,这个最可怕的事情,别人全能人,自然全能角度衡量,不仅要完成工作,还要搞懂原理,具体你怎么搞,抽时间我不管,谁记得 因为忙碌工作,,现在5分钟内,把模糊感觉变成具体需求?无论大小,无论难易都接受。5分钟,提出一个好问题 就相当于完成20% ,因为不去做后果太可怕了,承受不了,
  4. 把模糊感觉变成一个具体问题 最低成本,最有效方式,公司架构师,项目经理,SRE是最直接了解事情根本根本的,他们项目支持,各种环境支持,各种问题支持,你根本不具备这样资源,更具备这样能力,让你设计项目可以吗不可以,让独立解决一个问题可以吗 不可以?,自放弃专门项目,专门问题自己练手,你会说,可以问他们呀,他们无数项目,无数个问题等着解决,根本没时间,关键自己自己说不出来,都是无效沟通,因此第一直觉就是第一生产力,也是最直接最重要一个问题,在坚持5分钟 完成30%
  5. 怎么做?别人怎么做,就跟踪怎么做,搜集别人写文章,别人视频,自己不停练习,练习,从h这样最简例子开始,不停演进,在演进,在技术资料面前,大家看到都是一样的
  • 不要说我不是专家,我不是领导,没有项目支持,没有客户驱动,都是瞎研究,无组织,无纪录,毫无价值和意义 公司百万千万客户项目你根本没有这个能力, 既然他出现在面前 ,就是说明是你需要急需要解决事情,是看的到,听到事情,伸手够到事情,不要100%了解,不要 拿出100%研究,至少想别人解释清楚 这是什么,最后别人一问三不知,让别人鄙视不如自己鄙视自己,从疑惑地方开始。

  • 自己探索一番,不过消耗你时间和精力,不到导致部落战争牺牲xx人,不会导致重大决策失败损失xxx 亿,你根本影响别人,公司早就不同岗位划分隔离好了。不会别人挣多少钱,不给比人造成多大影响,放下担心,专注目前15分钟 就是要做事情。

1.1 目录项 采用什么数据结构存储

大目录查找

主要内容

  • Linear (Classic) Directories
  • Hash Tree Directories
特性 线性目录(如Ext2) Htree目录(如Ext4)
查找效率 O(n)(需遍历所有项) O(log n)(哈希过滤)
适用场景 小规模目录(<1000项) 大规模目录(百万级项)
存储开销 较高(需额外索引块)
扩展性 差 Directory scalability 支持动态分裂与多级索引
来源:趣谈 Linux 操作系统

举例说明:

一个目录下多个文件

1
2
3
4
5
6
7
[root@watchpoints icfs]# ls -ltra |sort

drwxr-xr-x 3 root root   4096 3月  24 11:31 ..(上个目录)
drwxr-xr-x 4 root root   4096 5月  8 16:02 . (当前目录)
-rw-r--r-- 1 root root 4194304 5月  2 17:40 file1
-rw-r--r-- 1 root root 4194304 5月  2 17:40 file2
-rw-r--r-- 1 root root 4194304 5月  2 17:40 file3

目录本质也是一种文件,但是这种目录文件的内容,

是其下文件或目录的inode与文件名信息。

1
2
3
4
inode1  file1
inode2  file2
inode3  file3

当然了,这只是示意,目录中记录的条目并非这么简单了,但也并不复杂,结构体如下:

1
2
3
4
5
6
7
8
1914 struct ext4_dir_entry_2 {                                                                                                                               
1915     __le32  inode;          /* Inode number */
1916     __le16  rec_len;        /* Directory entry length */
1917     __u8    name_len;       /* Name length */
1918     __u8    file_type;
1919     char    name[EXT4_NAME_LEN];    /* File name */
1920 };
https://www.kernel.org/doc/html/latest/filesystems/ext4/dynamic.html#directory-entries
Offset Size Name Description
0x0 __le32 inode Number of the inode that this directory entry points to.
0x4 __le16 rec_len Length of this directory entry. Must be a multiple of 4.
0x6 __le16 name_len Length of the file name.
0x8 char name[EXT4_NAME_LEN] File name.
就是一个数组呀,
  • 适合目录下文件数目比较少的情况下,一个块存储。那么为了获取子文件的inode,一次io操作完成

  • 如果一个目录下有几十万个条目,一旦需要几十几百个block?需要多次IO怎么处理?

dir_index 特性:

  • 线性目录项不利于系统性能提升。因而从ext3开始加入了快速平衡树哈希目录项名称

  • Ext4基于HTree的增强方案,在已有数据块的结构基础之上,新增了一层或多层的hash索引

整体视角

场景假设:

假设目录/docs下有多个文件:file1.txtimage.jpgreport.pdf等, Htree的存储结构如下:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
(根索引块DX-block)
├── 哈希范围 [0-1000] → 指向数据块1 (DE-block)
│   ├── file1.txt (哈希值: 250)
│   └── image.jpg (哈希值: 800)
├── 哈希范围 [1001-2000] → 指向数据块2 (DE-block)
│   └── report.pdf (哈希值: 1500)
└── 哈希范围 [2001-3000] → 指向下一级索引块 (DX-block)
    ├── 哈希范围 [2001-2500] → 指向数据块3 (DE-block)
    │   └── data.csv (哈希值: 2200)
    └── 哈希范围 [2501-3000] → 指向数据块4 (DE-block)
        └── backup.zip (哈希值: 2800)

关键组件:

  1. DX-block(索引块):存储哈希范围与子块地址的映射(如[0-1000] → 块1
  2. DE-block(数据块):存储实际目录项(文件名、inode ID等),内部不排序,但通过哈希范围过滤—这个和原来存储方式一样
  3. 哈希值:由文件名计算得出,决定目录项所属的块。
对应代码

**Htree的根 :struct dx_root

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

Hash Tree Directories
https://www.kernel.org/doc/html/latest/filesystems/ext4/dynamic.html#directory-entries
// Htree 根索引块结构(兼容传统目录格式)
struct dx_root {
    // 伪造目录项:模拟传统目录的 "." 条目(当前目录)
    struct fake_dirent dot;       // 伪目录项头部(inode、rec_len等)
    char dot_name[4];             // 固定存储 "."
    
    // 伪造目录项:模拟传统目录的 ".." 条目(上级目录)
    struct fake_dirent dotdot;    // 伪目录项头部
    char dotdot_name[4];          // 固定存储 "..",
    
    // Htree 根索引元数据(关键控制信息)
    struct dx_root_info {
        __le32 reserved_zero;     // 保留字段
        u8 hash_version;          // 哈希算法版本
        u8 info_length;           // 固定为 8(
        u8 indirect_levels;       // 索引层级:0=仅根节点,表示间接索引的层数
        u8 unused_flags;          // 未使用标志位(兼容性保留)
    } info;
    
    // 哈希映射入口数组(动态长度,通过 entries[0] 定义柔性数组)
    struct dx_entry entries[0];   // 每个条目包含哈希范围及子块指针
};

上图来自EXT4方面专家阿里的DongHao,他是以EXT3为例,我太懒了,就不亲自绘EXT4的图了,都是一样的 索引项由结构体 dx_entry表示,本质上是文件名的哈希值和数据块的一个映射关系。

1
2
3
4
5
struct dx_entry
{
    __le32 hash;
    __le32 block;
};

如果我们要查找一个目录下面的文件名,可以通过名称取哈希。

通过索引树,我们可以将一个目录下面的 N 多的文件分散到很多的块里面,可以很快地进行查找

Ext4文件系统的目录索引采用两层哈希B树(Hash B-tree)结构 其本质是哈希表与B树的结合体

可以通过debugfs工具查看目录的哈希树信息

小王疑问:为什么ext4目录项索引采用选用 HTree,而不是B+

HTree 是一种专门用于目录索引的树形数据结构 ,类似于 B 树 。

它们的深度恒定为一级或两级,扇出因子较高,使用文件名的哈希值 ,并且不需要平衡 。

而是为了大目录场景专门设计的,HTree 索引用于 ext3 和 ext4 Linux 文件系统 ,并于 2.5.40 左右被合并到 Linux 内核中。

特性 Htree(Ext4目录) B/B+树(如MySQL索引)
索引键 文件名哈希值(非有序) 主键或索引字段值(有序)
存储粒度 目录项块(如4KB) 数据页或磁盘块(如16KB)
查询类型 精确匹配(等值查询) 范围查询、排序、最左前缀匹配
结构扩展 哈希冲突时分裂数据块 节点填充度不足时分裂或合并

HTree 与 B-tree/B⁺-tree 的比较

特性 HTree B-tree / B⁺-tree
树高 常数(1 ~ 2 层) 随数据量增加而增加
扇出 高(数千) 较低(几十到数百,取决于节点大小)
平衡 无需平衡 需分裂/合并以保持平衡
键排序 按哈希范围分布,不保证时序 保证键的有序存储
冲突处理 溢出块或二级索引 不存在哈希冲突(键唯一排序)
查找复杂度 O(1)~O(深度) ≈ O(1) O(logₙ N)
元数据开销 较小(只存哈希与指针) 较大(存键-值对或指针、维持平衡信息)

演示如下:

二层结构

上图展现了一个简单的两级 HTree 结构示例:

  • 根节点(Root Node):存储一组哈希范围和对应的指针,例如 [0–1000] → Leaf Node 1[1001–2000] → Leaf Node 2。查找时,先对文件名计算哈希值,落在某个范围内就跟随指针进入相应叶子节点。

  • 叶子节点(Leaf Nodes):包含目录项实际记录(或指向溢出块的链表),这里示例中:

    • Leaf Node 1 负责存储哈希值在 0–1000 范围内的文件名条目;
    • Leaf Node 2 负责存储哈希值在 1001–2000 范围内的文件名条目。

HTree 关键点:

  1. 定深度:此例中总共两层,深度不会随着条目增长而变化,定位只需访问根+叶,访问次数恒定。
  2. 高扇出:在真实场景中,一个节点可包含数百到上千个哈希范围/指针,进一步减少深度。
  3. 哈希索引:使用哈希值作为键,不需要维护有序性,不进行节点分裂或合并,简化元数据更新并加速查找。

By default in ext3, directory entries are still stored in a linked list, which is very inefficient for directories with large numbers of entries.

The di-rectory indexing feature addresses this scalability issue by storing directory entries in a constant depth HTree data structure, which is a specialized BTree-like struc-ture using 32-bit hashes

Htree操作

Htree是持久存储于目录的数据块中,用来维护目录项布局的一种持久化数据结构。针对Htree有以下操作:

  • 查找(lookup):在htree中查找目录项或者查看某文件名是否存储于该目录;
  • 插入目录项:在htree定位路径的DE-block中插入一个目录项;
  • 删除目录项:在htree定位路径的DE-block删除一个目录项;
  • 分裂DE-block:如果目录项正在插入一个满的DE-block,那么将会分配一个新的块,原来的DE-block中一半的目录项将会迁移到新分配的块中;—不需要重新调整平衡
  • 分裂DX-block:在分配一个新的DE-block时,需要将它插入到父DX-block。当DX-block满了的时候,会造成DX-block的分裂;—不需要重新调整平衡

1.2 inode采用什么数据结构进行存储?

别人咀嚼过的内容,可能过时内容不是ext4的

1
2
3
4
https://github.com/torvalds/linux/blob/master/fs/ext4/ext4.h#L771
struct ext4_inode
		__le32  i_block[EXT4_N_BLOCKS];/* Pointers to blocks */

这个是ext3结构,来源趣谈操作系统

ext3 文件系统使用间接块映射方案,提供从逻辑块到磁盘块的一对一映射。

这种方案对于稀疏或小文件非常有效,但对于较大文件的开销很高 现在你应该能够意识到,这里面有一个非常显著的问题,

对于大文件来讲,我们要多次读取硬盘才能找到相应的块,这样访问速度就会比较慢。

ext4_extent 就像是一张"纸条”,用来记录文件里一段连续数据在硬盘上的位置和长度,比 Ext3 记"每一块"的方式要高效得多.

The new ext4 filesystem: current status and future plans

来源:Ext4文件系统之文件数据组织

疑问:不对呀,从数据结构定义 根本和An extent tree 没有关系呀?

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
https://github.com/torvalds/linux/blob/master/fs/ext4/ext4.h
/*
 * Structure of an inode on the disk
 */
struct ext4_inode {
	__le32	i_block[EXT4_N_BLOCKS];/* Pointers to blocks */
}

An extent tree is a data structure that maintains the extents associated with an inode.

The extent tree helps in faster traversal and retrieval of data


The `i_block` field stores structures such as `struct ext4_extent_header`, 

`struct ext4_extent_idx`, and 

`struct ext4_extent`, 
which are integral components of the extent tree.

Each of these structures have a size of 12 bytes


# 查看 inode 的 extent 树
debugfs /dev/sda1
debugfs: stat <inode号>
# 输出示例:
extent_header (eh_depth=2, eh_entries=3)
extent_idx 0: logical 0..1000  physical 8192
extent_idx 1: logical 1001..2000  physical 12288
...

来源:https://blogs.oracle.com/linux/post/understanding-ext4-disk-layout-part-2

在 ext4 文件系统中, __le32 i_block[EXT4_N_BLOCKS] 数组通过 B+树结构 实现 extent(区段)关系

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
https://github.com/openwrt/make_ext4fs/blob/master/ext4_extents.h

struct ext4_extent_header {
    __le16 eh_magic;    // 魔数(标识有效性,固定为 0xF30A)
    __le16 eh_entries;  // 当前节点包含的 extent 或索引项数量
    __le16 eh_max;      // 节点最大容量(可存储的项数)
    __le16 eh_depth;    // 树深度(0 表示叶子节点,>0 表示索引节点)
    __le32 eh_generation; // 树版本(用于校验)
};

eh_depth=0:直接指向叶子节点(即文件数据块映射)

eh_depth>0:指向中间索引节点,需递归遍历

i_block[3]~i_block[15] 共 12 个元素(每个 4 字节)动态存储两类数据:

  • 叶子节点ext4_extent 结构):描述文件逻辑块到物理块的连续映射
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
struct ext4_extent {
    __le32 ee_block;     // 起始逻辑块号
    __le16 ee_len;       // 连续物理块数量(最大 32768)
    __le16 ee_start_hi;  // 物理块号高 16 位
    __le32 ee_start_lo;  // 物理块号低 32 位
};

struct ext4_extent_idx {
    __le32 ei_block;     // 当前索引覆盖的最大逻辑块号
    __le32 ei_leaf_lo;   // 下一层节点物理块号低 32 位
    __le16 ei_leaf_hi;   // 下一层节点物理块号高 16 位
};
  • 索引节点ext4_extent_idx 结构):指向下一层 B+树节点
1
2
3
4
5
6
7
    struct ext4_extent_idx {
    __le32 ei_block;     // 当前索引覆盖的最大逻辑块号
    
    __le32 ei_leaf_lo;   // 下一层节点物理块号低 32 位
    __le16 ei_leaf_hi;   // 下一层节点物理块号高 16 位
};

来源:趣谈操作系统

请问:这个图片隐藏什么内容,数组 怎么存储一个tree结果呢?

如果文件不大,inode 里面的 i_block 中,可以放得下一个 ext4_extent_header 和 4 项 ext4_extent。所以这个时候,eh_depth 为 0,也即 inode 里面的就是叶子节点,树高度为 0。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
┌─────────────────────── inode  i_block[15] 数组 ───────────────────────┐
                                                                           
  ext4_extent_header (eh_depth=0)                                           
  ├── eh_magic: 0xF30A                                                     
  ├── eh_entries: 4 (有效 extent 数量)                                      
  └── eh_max: 4 (最大容量)                                                 
                                                                           
  ext4_extent 1                                                            
  ├── ee_block: 0         逻辑块起始号                                     
  └── ee_start_lo: 4096  物理块起始号                                      
                                                                           
  ext4_extent 2                                                            
  ext4_extent 3                                                            
  ext4_extent 4                                                            
└───────────────────────────────────────────────────────────────────────────┘

如果文件比较大,4 个 extent 放不下,就要分裂成为一棵树,eh_depth>0 的节点就是索引节点,其中根节点深度最大,在 inode 中。最底层 eh_depth=0 的是叶子节点

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
                                      ┌───────────────┐
                                       inode       
                                       i_block 数组  
                                      ├───────────────┤
                                       根节点         
                                       (eh_depth=2)  
                                      └──────┬────────┘
                                             
                          ┌──────────────────┼───────────────────┐
                                                               
                    ┌─────────────┐    ┌─────────────┐    ┌─────────────┐
                     索引节点块         索引节点块         索引节点块    
                     (eh_depth=1)      (eh_depth=1)      (eh_depth=1) 
                    └──────┬──────┘    └──────┬──────┘    └──────┬──────┘
                                                                
               ┌───────────┘                  └───────────────┐   └───────────┐
                                                                             
        ┌─────────────┐                                ┌─────────────┐    ┌─────────────┐
         叶子节点块                                     叶子节点块         叶子节点块    
         (eh_depth=0)                                  (eh_depth=0)      (eh_depth=0) 
        └──────┬───────┘                                └──────┬───────┘    └──────┬───────┘
                                                                                
        ┌─────────────┐                                ┌─────────────┐    ┌─────────────┐
         数据块                                        数据块            数据块       
         (物理块)                                      (物理块)          (物理块)     
        └─────────────┘                                └─────────────┘    └─────────────┘

i_block数组的两种模式

请一定看 https://docs.kernel.org/6.0/filesystems/ext4/dynamic.html#the-contents-of-inode-i-block inode.i_block can be used in different ways.

在 ext4 中,i_block数组(定义于 struct ext4_inode)有两种使用模式,由 i_flags 中的 EXT4_EXTENTS_FL 标志位决定:

  1. 传统间接块模式(兼容 ext2/ext3)
    • i_block[0-11] 直接存储数据块号,i_block[12-14] 指向间接块(一级、二级、三级)
    • 适用于未启用 extent 的文件或旧版本兼容场景。
  2. extent B+树模式
    • i_block 存储 B+树的根节点,包含 ext4_extent_header 和多个 ext4_extentext4_extent_idx
    • 启用条件:文件创建时设置 EXT4_EXTENTS_FL 标志(通过 ext4_set_inode_flag() 函数

演示ext4 extent B+树的形成过程

3.1 根节点4个extent插入过程

最开始,ext4 extent B+树是空的

好的,现在我们把这个ext4_extent插入到ext4 extent B+树,如下所示:

好的,现在当然需要3个ext4_extent保存这3段逻辑块地址与物理块地址的映射关系,并插入到ext4 extent B+树,全插入后如下所示:

3.2 根节点下的叶子节点extent插入过程

image.png image.png image.png image.png 3.3 根节点下索引节点的创建

疑问2:IO读写过程

上来 先别直接分析io过程过程 ,假如io高楼大厦的话,那么 第一次地基是什么

文件拆分

  1. 如何创建一个文件 mkdir a b c 过程是什么(readdir)
  2. 如何从目录下查找一个文件 cat /mnt/icfs/test/a
  3. cat /mnt/icfs/test/a
  4. 和上面数据结构有什么关系?

流程分析

dd if=/dev/zero of=/root/c++/test bs=1M count=16

blktrace -d /dev/loop0 -o - |blkparse -i -

image.png

image.png

image.png image.png

image.png image.png

请问疑问:文件io读过程,文件目录怎么读取,内容怎么读取

  • Directory Entry Lookup in ext4

  • When we request the kernel to look up a file, the kernel goes through the following process:
    当我们请求内核查找一个文件时,内核会经历以下过程:
  1. It obtains the inode and dentry of the parent directory.
    它获取父目录的 inode 和 dentry。
  2. From the inode, it reads the extent tree information and retrieves the location of the dx_root of the hash tree (htree).
    它从 inode 中读取范围树信息并检索哈希树 (htree) 的 dx_root 的位置。
  3. Using the hash value of the requested file, it traverses through the htree to locate the leaf block that contains the directory entry (dirent) of the requested file.
    使用所请求文件的哈希值,它遍历 htree 来定位包含所请求文件的目录条目(dirent)的叶块

对比:

  • CephFS 则通过碎片化将单一目录拆分,客户端可并行地查询不同碎片,并利用 RADOS 的高并发访问特性避免单节点 I/O 瓶颈。
  • CephFS 的目录查找仍然依赖 MDS 授权(capabilities)及碎片映射算法,但文件数据和多数元数据读取可 绕过 MDS,直接与 OSD/RADOS 交互,提升可扩展性
阶段 ext4 (HTree) CephFS (MDS + dirfrags)
父目录 inode 获取 dcache → page cache → 磁盘读取 本地 capability 缓存,必要时向 MDS 发起 lookup
文件布局定位 extent tree → dx_root → 磁盘物理块 MDS journaling → RADOS metadata pool → 客户端缓存 inode 布局
目录项查找 HTree hash 遍历 → dirent 目录碎片化 → RADOS 对象直接读取 → 在片段中查找 dentry

从上述对比可见,ext4 完全在单机层面依赖页缓存和 HTree,

而 CephFS 则在集群环境下通过 MDS 分发元数据与目录碎片化设计, 实现了面向大规模并发和海量条目的可扩展目录查找【大规模 通过添加机器实现,在单个数据结构设计不合理,还是常规map set实现】

. 客户端如何"知道"数据在哪 3.1 客户端侧计算

  1. 客户端通过 librados 拉取最新 CRUSH Map。
  2. 写入时,库根据对象名/PG 走 CRUSH 算法,计算出 Primary 和 Secondary OSD 列表。
  3. 读取时,同样用 CRUSH 算法计算并直接联系相应 OSD,无需 MDS 或 MON 中

青铜疑问:在写文件过程中

第一手资料

[1] An Introduction to the Linux Kernel Block I/O Stack

[2] 论文: Rearchitecting Linux Storage Stack for µs Latency and High Throughput

  • 原文:https://www.usenix.org/conference/osdi21/presentation/hwang
  • 翻译:重新构建 Linux 存储堆栈以实现 μs(微妙) 延迟和高吞吐量
  • 社区中普遍认为,使用 Linux 内核堆栈时不可能实现 μ 级的尾部延迟–如何解
  • blk-switch 为 Linux 存储堆栈引入了一个按内核、多出口队列块层架构
  • 主要介绍了两种存储栈结构:
  1. 现有存储堆栈:低延迟或高吞吐量,但不能同时满足两者。 在 Linux 存储堆栈的早期版本中,所有核提交的请求都在一个队列中处理 完全公平调度程序 (CFS):在共享内核的应用程序之间平均分配 CPU 资源,毫秒时间尺度,分配时间
  2. SPDK(广泛部署的用户空间堆栈)
  3. USENIX ATC ‘19 - Asynchronous I/O Stack: A Low-latency Kernel I/O Stack for Ultra-Low Latency SSDs
  4. https://www.youtube.com/watch?v=ri1MrvJnbSU
  5. https://www.youtube.com/watch?v=BBONTH-BZvU&t=352s
【3】 Ext4(The fourth extended file system)
  1. 论文:The new ext4 filesystem: current status and future plans
  2. https://github.com/MoonShadowzzc/Data-Structure
  3. 刨根问底:Ext4文件系统目录下可以存放多少子文件
  4. Lustre并行目录操作的设计与实现 ✅ note 结构可视化
  5. EXT4 的 dir_index 特性✅阅读完成
  6. [fs] 与ext4_dir_entry_2相关的ext文件系统知识 ✅ 阅读摘要 目录也是文件
  7. https://ty-chen.github.io/linux-kernel-fs/ # Linux操作系统学习笔记(十一)文件系统
  8. 一篇文章理解Ext4文件系统的目录
  9. ext4 Data Structures and Algorithms

  10. How ext4 File system is changing directory entry structure form linear to Htree?
  11. 理解 Ext4 磁盘布局,第 2 部分 https://blogs.oracle.com/linux/post/understanding-ext4-disk-layout-part-2

3. Linux内核源码:ext4 extent详解

4. 文件系统技术内幕