文件系统核心解析:从逻辑结构、物理结构到磁盘存储原理
文件管理这块很多人在学校上课或自学的时候都觉得是“背概念”什么逻辑结构、物理结构、FAT表、索引节点一个个名词背得滚瓜烂熟一到实际排查问题或者做系统设计就傻眼。我在实际工作中遇到的不少同事甚至包括一些工作两三年的研发对文件系统怎么把数据落到磁盘上这件事认知都停留在“反正有系统帮我管”的程度。直到某天线上日志文件删不掉、磁盘空间异常、或者写文件突然变慢才想起来翻操作系统书。这个标题把“文件逻辑结构、物理结构、磁盘基础”串在一起本质上是在回答一个核心问题文件系统的设计者是怎么在又快又省空间又要可靠这三者之间做权衡的。这篇文章我就用实际工程里的视角把这个知识链条拆开讲透不光学完能应付面试更重要的是你以后做存储、做数据库或者只是单纯想搞明白“为什么我的磁盘碎片化这么严重”都能用得上。1. 文件管理整体思路从用户视角到底层存储的映射1.1 文件系统到底在解决什么问题你先想一个最简单的问题你写了一个文本文件保存的时候它是一串字节流比如“你好世界”这四个中文字符如果你用UTF-8编码它会占据12个字节。这个文件的文件名叫hello.txt它在你的桌面目录下。就这么一个简单的东西操作系统背后要干多少活它要知道这个文件名对应哪些磁盘扇区要知道文件从哪开始到哪结束要知道文件创建时间、修改时间还要知道哪块磁盘空间是空闲的可以被覆盖以及哪些空间已经被占用不能碰。这一整套的管理工作就是文件系统。它之所以复杂是因为它要在一个机械结构或者电子存储介质上建立一个逻辑上方便人类使用的“目录树—文件”模型。文件管理这个模块在操作系统里面其实是承上启下的一个层次上面要接系统调用接口让用户程序可以open、read、write、close下面要对磁盘设备驱动屏蔽物理细节。在实际的设计中有三个核心问题始终贯穿怎么组织文件中数据的顺序让用户感觉它是一个连续的字节流怎么将文件中逻辑上连续的字节映射到物理上可能不连续的磁盘块怎么高效管理磁盘这个慢速设备减少机械寻道带来的性能损失。这三个问题正好就对应了标题里的“逻辑结构—物理结构—磁盘基础”。1.2 为什么逻辑结构和物理结构要分开看这是很多初学者最容易混淆的一层。逻辑结构描述的是“用户眼中”文件长什么样而物理结构描述的是“磁盘眼中”文件怎么存放。搁到代码里面类比逻辑结构就是接口Interface物理结构就是具体的实现Impl。你向文件系统写入一段数据时它先把这段数据放在页缓存Page Cache里然后后续某个时间点再决定把它写入哪些具体的扇区。逻辑结构决定了读写的API语义物理结构决定了实际IO的布局。一个非常典型的例子是数据库的表文件。在逻辑结构上MySQL的InnoDB把表数据组织成B树这是一种索引结构但它背后的磁盘文件很大物理上可能被切分成很多个区段Extent分散在磁盘的不同位置。如果物理结构设计得不好导致随机IO过多整个数据库的性能就会急剧下降。所以说理解这两者的区别不仅是应付考试更是后续做性能优化和故障排查的基础。考虑到文件是磁盘上最核心的数据抽象下面我就把这两层结构的具体形态和取舍拆开讲。2. 文件逻辑结构用户眼中的文件到底长什么样2.1 无结构文件与定长记录文件文件逻辑结构按最简单的分类可以分为两类无结构文件流式文件和有结构文件记录式文件。无结构文件最常见它就是一段字节流没有内部结构或者说不关心内部结构。比如各种文本文件、图片文件、可执行文件系统只管给你一串字节至于里面是文本还是图片编码完全是应用层的事情。在这种文件上操作系统提供的操作就是读某偏移地址的一段字节、写某偏移地址的一段字节。这也解释了为什么很多程序员觉得文件就是个“大数组”你随机读写时跟访问内存数组的感觉差不多。有结构文件则是把文件内部划分成一条条逻辑记录常见于早期的数据库、成绩单管理、账务系统等场景。这里又能细分成定长记录和变长记录。定长记录文件里每条记录的长度是固定的比如你存一批学生的学号每个学号固定8字节那第n条记录的起始位置就能通过n × 8直接计算出来这种文件的随机访问极其高效本质上是数组。变长记录就麻烦一些比如一个字段长度不定的JSON日志文件你很难通过简单的公式直接定位第n行日志一般就需要配合行索引或者附加的结构来辅助定位。从实际应用来看现在的操作系统文件系统面上几乎都是无结构文件为核心因为这种设计简洁、通用性最强。凡是需要内部结构、要索引、要记录分隔符的都交给应用层去解析。这个哲学一直延续到今天操作系统保持简单复杂结构统统上浮到应用层。2.2 顺序访问、随机访问与操作接口的差异逻辑结构的划分又决定了这个文件支持的访问模式。顺序访问就是老老实实从头到尾读或者从当前位置继续读随机访问就是在文件里跳着读先读到第500K位置再回去读第100K位置。对无结构文件来说随机访问的实现方式就是修改文件读写的偏移量。在Linux里你可以用lseek这个系统调用把文件偏移指针移动到指定位置然后再调用read或者write这就完成了随机访问。对有结构的定长记录文件随机访问更是小菜一碟直接算偏移就行。真正的痛点在于变长记录文件上的随机访问。举个例子一个2GB的文本日志文件每行长短差异很大你想直接读最后100行如果不是先扫一遍整个文件拿到行索引几乎没法精确跳转。实际工程里常见的方案就是给这类文件额外配一个稀疏的偏移索引或者干脆用专门的日志存储系统来管理。这说明一个道理逻辑结构选型和上层应用的数据访问模式高度相关决定一个组件的设计时不应只看“能存”更要看“怎么读”。顺着这个思路文件内部结构梳理清楚了接下来就得关心这些字节到底放到磁盘哪里这就是物理结构登场的时刻。3. 文件物理结构数据到底存放在磁盘哪里又是怎么被找到的3.1 连续分配、链接分配与索引分配三种方案的经典取舍物理结构最核心的问题是把逻辑上的连续字节流映射到磁盘上的物理块集合。常用的方案有三种各有各的适用场景和致命伤。连续分配是“最理想但不现实”的方案。它在磁盘上找一块连续的空闲区域把文件的全部数据块放在里面文件目录项只需要记录“起始块号 长度”就够了。优点是简单粗暴随机访问极其高效因为只需一次寻道就能把整个文件区域扫出来缺点也极其致命——文件没法动态增长你在中间插入数据基本上不可能而且长时间使用后磁盘碎片化会越来越严重。这就是为什么现代通用文件系统基本不采用纯粹的连续分配。但有些场景还是会借鉴它比如光盘上的ISO9660文件系统文件本来就是刻录之后不变的连续分配很合适。链接分配是“解决碎片化但牺牲随机访问”的方案。它给每个文件数据块都留一个指针指向下一块。FAT文件系统就是这类结构的代表它用一个单独的区域File Allocation Table保存所有块的链接信息目录项只记录文件的第一块后续块就顺着表查下去。优点是文件可以任意增长磁盘碎片也可以被使用缺点是随机访问慢——你要读第1000个块就不得不从第一块开始顺着链子走1000步。这种方案在早期软盘时代算是黄金方案因为那时候磁盘容量小文件小顺序访问是绝对主流。但放到今天动不动几个GB的文件这种结构就力不从心了。索引分配是当前主流文件系统的正解它在文件创建时分配一个索引块里面存放这个文件所有数据块的块号数组类似于给文件做一个“块号清单”。拿数组类比的话连续分配是“连续数组”链式分配是“链表”索引分配是“指针数组”。这样随机访问就快多了要读第n块直接查索引块中第n个表项定位到物理块号就可以发起读取。缺点是每个文件要额外消耗一个索引块而且还存在一个“大文件索引块不够用”的问题。所以大文件怎么处理经典的演进方案就是多级索引和混合索引。多级索引就是索引块里放的不是数据块号而是下一级索引块的块号。混合索引则是把几种方式混合起来用比如文件的前12个数据块号直接放在inode里直接寻址超过12块之后再用一级间接索引如果还更大再用二级间接索引。这就是Unix System V inode的经典设计。为了让你直观感受这个设计的巧妙我拿一个小例子算一下假设文件系统块大小是1KB块号占4字节那一个索引块可以存放256个块号。一个inode里先放12个直接块指针那文件能直接管理12KB一级间接索引指向一个索引块这个索引块又可以指向256个数据块也就是256KB二级间接索引则能管理256 × 256 65536个数据块也就是64MB。三级索引再往上就是16GB的量级。这种阶梯式的结构对小文件开销极小对大文件又能支持超大容量怪不得能成为几十年不衰的经典方案。3.2 现代文件系统在物理结构上的演进Ext4的Extent与B树经典的索引分配有一个现实的浪费问题如果一个文件的数据块是连续的磁盘分配时正好找到了一段连续空间使用索引块依旧需要一个指针一个指针地记录占用了好多额外存储这不符合实际场景里的空间效率。所以现代文件系统纷纷改用了“区段Extent”的概念。Ext4里就用extent树替换了传统的直接/间接块映射。所谓extent就是一段连续的磁盘块序列描述为一个起点块号 长度。对一个几十MB的连续文件可能只需要很少的几个extent条目就够了而不像索引分配那么烦琐地要求逐块记录。这就把“索引分配支持随机访问”和“连续分配节省元数据”的优势结合在一起了。XFS则更激进它的数据块寻址用的是一个B树结构专门用于管理文件物理块的映射。B树天生支持高效的查找、插入和删除对付大文件时的性能远胜传统的多级索引。为什么数据库和文件系统最终都走向B树核心原因就是它把随机点查询和高效区间扫描统一到了一个结构里还能通过调整节点大小适配磁盘IO特性。你在看分布式存储系统比如某个开源对象存储时也能看到它们对逻辑块到物理块映射用B树或类似结构的影子。这算是一个规律级的现象。3.3 物理结构里的核心配角目录项与空闲空间管理文件的物理位置记录是一方面另一个同等重要的是目录和空闲空间管理。目录项dentry或dir_entry负责把文件名和inode号关联起来。一个目录其实就是一个特殊文件里面存放着一个个目录项每个目录项包含文件名、inode号、文件类型等信息。目录项的存储方式也对文件系统性能有决定性影响。老式的FAT文件系统目录就是个线性表你要查找某文件就得从头到尾线性扫描文件一多就慢得离谱。而ext4通过使用目录项树Htree索引优化了大目录下文件名查找的性能大目录里创建、删除、查找一个文件都接近常数级。空闲空间管理同样分策略。最传统的做法是位图bitmap拿一块内存或磁盘区域每一位对应一个数据块0表示空闲1表示占用。这个方法的优点是查找和更新速度都极快一次位操作就能判断缺点是位图本身可能很大而且为避免频繁写入导致性能瓶颈文件系统往往会把它缓存在内存中。相对地有些文件系统也用空闲链表或B树管理空闲区域各有优劣。但这块性能好坏直接表现到“往磁盘写一个大文件”时的分配速度所以也有一些现代文件系统的分配器做了优化例如尽量为文件分配连续空间以减少碎片化。物理结构听完你肯定已经意识到文件系统的很多设计选择都是因为磁盘的物理特性使然所以要真正理解为什么文件系统长这样还得蹲下来看看磁盘本身。4. 磁盘基础机械硬盘的物理特性与性能约束4.1 盘面、磁道、扇区与柱面磁盘到底是怎么组织数据的磁盘由盘片、磁头、主轴电机、磁臂等核心部件组成。盘片上下两面各有一个磁头数据就记录在盘面上的同心圆环中这些圆环叫磁道。每个磁道又被划分成若干个扇区传统上扇区大小是512字节现在大容量机械硬盘基本都转用4K扇区先进格式化技术。从物理地址看磁盘上一个具体的数据块位于哪个扇区需要用“柱面号—磁头号—扇区号”这个三元组来定位。柱面就是指所有盘面上同一半径磁道的集合因为它对应的所有磁道可以被同一个磁头位置访问所以访问柱面意味着无需移动磁臂。读取数据时磁头必须先移动到目标磁道上方——这是寻道操作然后等待盘片旋转让目标扇区转到磁头下——这是旋转定位操作随后才能开始读写——这是传输操作。这三个操作的时间特性差异非常大。寻道时间通常是几毫秒到十几毫秒旋转延迟平均是磁盘旋转半圈的时间按7200转/分钟算的话一转是8.33毫秒半圈大概4.17毫秒。而传输时间相对要小得多读一个4KB的块在顺序场景下几乎可以忽略。所以你实际观察到的磁盘读写性能绝大部分都消耗在寻道和旋转等待上这也是为什么随机IO性能远低于顺序IO。4.2 一块普通的机械盘在真实IO负载下表现得有多“慢”我先给你一个感性的认识。某个普通7.2K RPM企业级机械硬盘顺序读带宽大概150MB/s左右顺序写可能也在120~150MB/s但一旦变成随机4K读写每秒只能完成大概100~200次IO操作换算成带宽只有0.4~0.8MB/s差距是百倍级别。你可能会疑惑一块硬盘的物理介质本身是同一个盘片同样的转速为什么随机和顺序差距能拉这么大呢核心就在于磁头寻道的物理代价。顺序读写时磁头可以连续地从一条磁道过渡到下一条相邻磁道大多数情况下几乎不需要大幅寻道甚至可以通过预读把后续可能访问的数据也搬进缓存效率自然高。而随机读写时每换一个数据块都要让磁头跑来跑去先移动再等盘片转时间都耗在“路程”上。这也是为什么数据库、消息队列、日志系统这些底层存储都强调“顺序写”的原因之一。很多号称性能很强的存储引擎本质上是把用户的随机写操作“假装成”顺序写落盘比如有些KV存储和日志格式的存储都用append-only的设计把更新的数据作为新记录追加到文件末尾再用后台机制做合并整理正是吃透了磁盘顺序访问这个特性。4.3 磁盘调度算法操作系统是怎么排队处理IO的磁盘IO请求并不总是单个出现更多时候是多个进程同时在发请求。如果OS像一个老实的办事员来一个处理一个那磁头会在磁盘上各处乱窜效率低下。于是操作系统实现了磁盘调度算法对IO请求队列里的若干请求进行重排。先有先来先服务FCFS这是最公平也最愚蠢的方案完全不管寻道距离会被随机负载打到性能谷底。然后是最短寻道时间优先SSTF它总是选择离当前磁头位置最近的请求能显著降低平均寻道时间但缺点是低优先级的远端请求可能长期得不到服务产生“饥饿”。再往后是SCAN算法电梯算法磁头从一端开始向另一端移动途中服务所有经过磁道的请求到头后反向再扫回来就像电梯一样上下各一次。这个算法解决了饥饿问题而且磁头移动模式比较规律。C-SCAN只在一个方向服务返回时直接跳到另一端这样对所有磁道的响应更均匀还有SPTF等基于扇区最优的更细粒度调度变体。在实际操作系统中现代的Linux内核在块层用的是基于deadline或mq-deadline的调度算法在保证吞吐量的同时注意把迟到的、快要超时的请求优先处理并倾向于合并合并相邻的IO请求形成顺序请求模式。理解了这些调度机制你就能明白为什么同一个服务器规格数据库跑得好不好OS挂载参数和调度器选型的影响竟会那么大。4.4 固态硬盘和机械硬盘在文件系统设计上的根本差异SSD没有机械寻道随机读写速度远超机械盘但引入了新的问题擦除界限块是写入擦除的基本单位但操作粒度不对称和写放大。如果一个文件系统针对机械盘设计每次写小数据块都去修改原位置在SSD上就会导致频繁擦块、写放大加速磨损。再叠加一个更常见的现代制约即在随机写入写入量大的场景文件系统层的机制可能成为限制因素。现代SSD主控内部有自己的FTL层这个FTL负责把上层文件系统的逻辑块地址映射到物理闪存页它还包含磨损均衡、垃圾回收等机制。你从OS层面看到的块设备其实已经是被SSD主控“包装”后的抽象视图。所以针对SSD的文件系统尽量把写入进行追加式写入让物理页尽量顺序写入减少擦除周期比如F2FS其基本的思路就是采用Log-structured结构把写入集中到连续区域并配有额外的clean操作线程在后台进行垃圾回收。这就解释了为什么数据库或文件系统在SSD上的很多优化思路和机械盘时代不一样。传统上很多“高手教你优化磁盘”的招数其实已经是过时的产物了。5. 实操指导在Linux环境下验证文件系统结构和磁盘特性5.1 用stat、debugfs和filefrag解剖一个文件的物理布局理论知识讲再多不如在系统里亲手摸一遍。我在Linux服务器上经常用三个命令来观察文件系统的运行状态正好对应我们前面讲的三层结构。stat命令是第一步它直接列出文件inode里的核心元数据。比如你执行stat hello.txt能看到文件大小、块数、IO块大小、inode号、权限、时间戳。注意里面的Blocks字段它表示文件占用了多少个512字节扇区而IO Block通常显示4096表明文件系统逻辑块大小是4KB。如果文件是稀疏文件你还能通过这个字段发现文件实际占用的块数远小于按大小换算出的块数。第二步是用filefrag来查看文件的物理碎片情况。比如filefrag -v hello.txt它会列出这个文件在磁盘上被分配成了几个extent每个extent的物理起始块号和长度。如果文件是刚创建且连续写入的你可能只看到1个extent如果文件经历过大量随机写入和删除后再写就可能有几十个extent。这个命令是观察物理结构的利器也是验证“顺序写入产生连续分配”的最好手段。第三步是更底层的debugfs对于扩展文件系统可以用它直接查看inode的内容和块寻址结构。比如使用debugfs -R stat inode号 /dev/sdX它会把inode的相关信息以及直接块、间接块等字段都打印出来。你可以根据自己的环境试试把一个大文件和一个几百字节的小文件对比看能明显看到小文件直接使用inode里预分配的直接块指针而大文件则进入了extent树或者间接索引的领地。这三步操作下来你在书本上学的“inode存元数据”“extent映射物理块”这些概念就变成活生生的可观察、可验证的行为。有了这些基础你再去看别人分析文件系统性能问题的文章理解起来就完全不在一个层级了。5.2 通过创建文件系统、观察碎片化、对比调度器效果来直观感受磁盘基础除了看还可以动手做一个验证方案。我在给一些朋友做培训时经常用一个非常直观的对比实验来展示文件系统分配策略和磁盘IO特性的重要性。准备一块独立的磁盘或一个loop设备先格式化成ext4挂载后用一条脚本创建500个小文件每个4KB大小反复几次先创建、再删除其中一半、再填充新文件。整个过程结束后用filefrag看新文件的extent数量你会发现碎片化现象很普遍。然后换一个场景一次性顺序写一个1GB的大文件再查看它的extent数量大概率是很少的连续段。这两个场景对比能让你一眼看出文件系统在分配策略上的倾向性和碎片产生的来源。衡量磁盘IO性能也很方便Linux自带fio工具。可以用fio分别测顺序读、顺序写、随机读、随机写四种模式下的IOPS和带宽几行配置就能跑完比如fio --nameseqread --rwread --bs1M --size1G --numjobs1 --runtime30 --group_reportingfio --namerandread --rwrandread --bs4K --size1G --numjobs4 --runtime30 --group_reporting这样测出来的数据差异会非常直观基本都是数量级的差别。你还可以顺手把调度器切成none或者mq-deadline再测一轮看看对随机IO的影响就明白调度器在真实系统中的意义了。5.3 这些知识在系统设计中的实际应用日志落盘、数据库文件、容器镜像理解了文件系统的这三根支柱你在日常研发中看很多技术方案都会豁然开朗。日志系统是顺序IO的典型受益者。像Kafka这种消息系统所有消息都追加到日志分段文件的末尾消费时也是顺序读为主天然契合磁盘顺序读写的优势。如果换成随机写小消息性能就惨不忍睹。MySQL的redo log也是同样的道理它在崩溃恢复时为了保证性能和可靠性一定要求顺序写足够快。数据库数据文件的设计则巧妙地同时利用了两类IO特性。一个事务提交时的关键信息用日志顺序写保证低延迟而实际数据页的落盘则在后台随机写配合组提交、双写缓冲这些机制尽量减小随机IO对系统的影响。一般数据库的调优很大一部分都是围绕“减少随机IO、提高顺序IO比例”在进行。容器镜像的分层存储也是文件系统物理结构的典型应用。容器镜像的每一层在宿主机上是多个目录下的文件底层是overlayfs实现的联合挂载。不同层的文件在文件系统物理块上可能完全分散所以运行多个容器时页缓存命中率、磁盘IO模式都可能受影响。这些细节在你做大规模容器化部署时就会变成实实在在的性能瓶颈。看完了应用场景和实验最后我把从这些实操和排查中沉淀出来的经验做个小结应该能帮你少走不少弯路。6. 常见问题与排查技巧实录6.1 实战排查日记大表查询突然变慢的定位过程有一次线上数据库实例的某个大表在查询时突然延迟飙升业务方反馈“全表扫描特别慢”。第一个直觉是慢SQL但看了执行计划发现索引没问题。后来我用iostat -x 1观察磁盘发现这块盘的%util一直在90%以上且await高到离谱而随机读IOPS却没多大变化。再用debugfs配合filefrag查看那个表空间文件发现它被切成了几百个extent且分散在整个磁盘上。进一步排查才知道原来是之前有同事做了一次批量删除和重建分区又开了自动扩展表空间文件在多次伸缩后碎成了一地。方案很直接用mysqldump导出再导入重建表空间或者在线做一次表空间重组finally之后查询延迟恢复正常磁盘的await也掉下来了。这个案例里物理结构的知识是定位根因的核心钥匙。还有一次某服务日志目录里有很多小文件发现清理脚本跑完以后服务还在反复创建和删除文件导致磁盘IO升高。实际上这就是典型的空闲块分配抖动因为文件系统要反复分配和释放零散的小块导致元数据操作频繁。后来我们把固定周期的日志清理改成了分批、小批量、低频清理效果立竿见影。6.2 常见问题速查表高频疑问与排查要点我把实践里被问得最多的问题整理成了一个表格照着查能节省不少时间。问题/症状常见原因排查/解决思路磁盘明明还有很大空间但写入新大文件报“磁盘满”inode耗尽即元数据空间不足用df -i查看inode使用率如果是100%就去清理小文件删除大文件后磁盘free空间没有立刻变大文件被进程占用inode仍指向数据块用lsof | grep deleted找到占用进程重启或让进程释放句柄大量小文件写入极其慢每次写文件都有inode分配、目录项更新、元数据日志写入开销合并小文件、调节mount参数或改用适合大量小文件的文件系统查询一个文件很慢但其实文件不大目录项太大或目录项碎片化严重检查目录的索引结构大目录可以考虑改用树形目录存储频繁随机读写时SSD也卡顿写放大严重例如频繁更新小范围的B叶子页减少小事务的提交频率调整刷盘策略或扩大页大小设置了noatime后性能还是没提升可能其他元数据更新时间戳负担依然存在查看是否是relatime仍然生效按需调整挂载参数这些排查思路本质都是从“逻辑层下探到物理层”的过程你可以顺着表格自己动手实践一番。6.3 实用避坑技巧与调参心得从挂载参数到文件系统选型最后分享几个我在不同操作系统环境里实践出来、比较有价值的调优/避坑要点。第一个是挂载参数。文件系统在挂载时有很多可以优化的选项。比如对很多日志型场景可以在mount时加noatime免去每次读文件都更新访问时间戳的开销对追求可靠性优先的场景则要合理设置commit值控制元数据多久刷一次盘。有时候一个看似微小的挂载参数在高频IO场景里引起的性能差距可以达到两位数百分比。第二个是块大小选型。创建文件系统时块大小是个需要权衡的参数。4K块适合大量小文件的通用场景能减少内部碎片如果你确定存的基本都是大文件比如视频文件、数据库的备份文件则可以把块大小调到更大。但注意块大小是格式化时确定的后期改起来非常麻烦所以一定要在建文件系统前想清楚业务的文件大小分布。第三个是对SSD和机械盘要有不同的文件系统选型态度。如果是纯机械盘环境采用顺序写友好的应用设计比什么玄学调优都重要而在SSD上关注写放大和磨损尽量选用支持TRIM/丢弃操作的文件系统挂载选项定期让系统执行fstrim——这是纯粹的SSD时代产物。很多年来人们从机械盘时代带过来的“碎片整理”习惯在SSD上是反效果的。这些坑和技巧都是我在真实生产环境里一步步踩出来的。有些问题书本上不一定会写但是性能和稳定性问题基本都出在这些容易被忽略的细节上。关于文件系统的知识我最后还想强调一点实际体会你在学校学操作系统时可能觉得逻辑结构、物理结构、磁盘调度这些都是孤立的考点但真正到了工程里它们始终是相互牵扯的一整个系统任何一个设计都没有绝对的好坏只有面向具体业务负载的取舍。想到某个存储引擎要把随机写变成顺序写想到某个文件系统要用B树管理extent你能从磁盘的物理特性出发推导出它的设计动机这些东西才算真正内化成了你自己的判断力。多拿几块盘、多格式化几个文件系统、多跑几次fio在这些实际操作中形成的体感比死记背书里的图有用得多。