磁盘是一种通过磁性原理进行数据存储和读取的设备,常用于存储操作系统、应用程序以及用户文件等。它通常由多个盘片组成,这些盘片通过旋转来提高数据存取速度
磁盘是计算机存储系统中非常重要的组成部分,负责持久化存储数据。通过不同类型的磁盘(如HDD、SSD、SSHD)以及不同的工作原理,磁盘提供了多样化的解决方案来满足不同的性能、容量和价格需求。对于现代计算机系统,SSD提供了极快的读取速度和较低的功耗,成为了主流的存储选择。而对于大容量存储,HDD 依然是性价比高的选择。
硬盘驱动器(HDD,Hard Disk Drive):
硬盘驱动器是最常见的磁盘类型,利用磁性存储来读写数据。硬盘内部包含多个磁盘盘片,这些盘片不断旋转,磁头通过电磁感应的原理在盘片表面读取和写入数据。
工作原理:
固态硬盘(SSD,Solid-State Drive):
固态硬盘是一种基于闪存技术的存储设备,不包含任何机械部件。SSD 的数据存储原理基于电荷在 NAND 闪存芯片中的存储。
优点:
缺点:
工作原理:
混合硬盘(SSHD,Solid-State Hybrid Drive): 混合硬盘结合了 HDD 和 SSD 的优点,通常包含一个大容量的机械硬盘和一个较小的固态硬盘。混合硬盘会将常用的数据或文件存储在 SSD 部分,以提高性能,而大容量数据存储则依然使用 HDD 部分。
磁盘的核心工作原理就是使用磁场和电流的变化来控制数据的存储与读取。具体来说,磁盘的工作可以分为以下几个步骤:
根据存储介质和传输方式,磁盘可以分为不同类型:
磁盘的逻辑结构是如何将物理存储划分为可管理的单位,以便计算机能有效地存储和检索数据。磁盘的逻辑结构包括以下几个层次:
扇区(Sector):
磁盘的最小数据存储单位是扇区(sector)。每个扇区通常由 512 字节或 4 KB 组成(现代磁盘也支持更大的扇区)。每个扇区都有唯一的地址,用于定位和访问数据。
簇(Cluster):
簇是操作系统在磁盘上分配空间的最小单位,通常由多个扇区组成。簇的大小通常是 4 KB、8 KB、16 KB 等。簇的大小决定了磁盘的存储效率和性能。
轨道(Track):
轨道是盘片表面上的同心圆,磁盘的每个盘片表面都有多个轨道。每个轨道由多个扇区组成,磁头通过磁臂定位到指定的轨道进行数据读取和写入。
柱面(Cylinder):
柱面是由多个盘片表面上具有相同位置的轨道组成的集合。每个柱面上包括磁盘中所有盘片的相同位置的轨道。例如,柱面 0 包含所有盘片的第一个轨道,柱面 1 包含所有盘片的第二个轨道,依此类推。
哪怕现在我只需要改一个比特位,也需要把磁盘中512位全部读到内存中
如何找到一个指定位置的扇区(CHS定址法): a. 找到指定的磁头(找到在哪个面)(Header) b. 找到指定的磁道(柱面)(Cylinder) c. 找到指定的扇区(Sector)
磁盘盘片旋转:定位扇区 磁头左右移动:定位轨道
文件其实就是在磁盘中占有几个扇区的问题
OS直接用CHS对设备进行管理的话耦合度太高
对磁盘可以将其抽象为一个线性结构,把磁盘每一面拉直拼在一起,线性结构每一个小段是一个扇区,最终把磁盘直接抽象为数组,sector
假设一个面有1000个扇区,10个磁道,未来通过下标可以确定扇面位置
可以得到H C S
对于操作系统来言,未来我们读取数据,可以以块为单位了
文件只需要记录自己的LBA地址
块大小=4KB(八个连续的扇区)
磁盘存在多个块,对磁盘进行分区管理,我们电脑的C,D盘就是一个分区,选取其中一个分区进行分析,分区里面进行分组,管理好一组就能管理好每一组,就能管理好每一个分区,这里用了分治的思想
上面的逻辑图与之对应
文件 = 内容 + 属性
文件在磁盘存储,本质是文件的内容+文件的属性数据,Linux文件系统特定:文件内容和文件属性分开存储
每个数据块固定4kb的大小
Linux中的文件属性是一个大小固定的集合体,inode是用于描述文件属性的结构体
inode内部不包含文件名!
每个文件都有一个唯一的inode,每个文件都有inode number,通过inode号来标识一个文件
inode里面会包含一个数组,这个数组会保存该文件会占用哪些数据块
我们寻找文件的时候,都必须先得到文件的inode编号,inode编号是以分区为单位的!
一个 磁盘分区 是磁盘的一个独立区域,可以被格式化为一个 文件系统。在文件系统中,文件(以及目录等对象)是通过 inode 来管理的。
在每个文件系统中,inode 编号是从文件系统的 inode 表中分配的。每个文件系统在创建时会分配一个 inode 表,这个表包含了该文件系统中所有文件和目录的 inode 信息。
例如,如果你有一个磁盘分区 sda1
和另一个磁盘分区 sda2
,它们各自有自己的 inode 编号空间:
sda1
中,inode 编号可能从 1
开始,到 N
(N 是分区中最大 inode 数量)。sda2
中,inode 编号也会从 1
开始,到 M
(M 是该分区最大 inode 数量)。每个分区的 inode 表是 独立的,所以 inode 编号对不同分区来说是不重叠的。
每个文件都有一个 inode 编号,该编号唯一标识文件的元数据。当我们查找文件时,操作系统通过目录项找到文件的 inode 编号,然后根据该 inode 编号查找 inode 结构来获取文件的详细信息。
/home/user/document.txt
)解析出该文件对应的 inode 编号。假设你有两个分区 /dev/sda1
和 /dev/sda2
,每个分区上都有一个文件系统(如 ext4)。文件系统分别管理它们各自的 inode 表:
/dev/sda1
的 inode 编号可能从 1
开始,最大值为 1000
,这些 inode 只在 /dev/sda1
分区的文件系统中有效。/dev/sda2
的 inode 编号可能从 1
开始,最大值为 2000
,这些 inode 只在 /dev/sda2
分区的文件系统中有效。如果你要查找文件 /home/user/file1.txt
,操作系统首先会解析路径 /home/user/file1.txt
,然后找到 /home/user/
目录项中包含的 inode 编号(比如 inode 编号 120
),操作系统会在 /dev/sda1
分区的 inode 表中查找 inode 120
。
现在,得到inode就知道在哪个分区的哪个分组里,然后根据inode编号直接在inode表里面就可以找到inode信息,找到了文件的所有属性和内容,那和文件名有什么关系呢?
在 Linux 文件系统中,文件名 和 inode 之间的映射关系是通过 目录项(directory entry) 来建立的。每个目录都有自己的目录项,每个目录项包含了文件的 名称 和指向该文件的 inode 的引用。简而言之,文件名是通过 目录文件(如 /home
、/etc
等)来与其对应的 inode 建立关联的。
目录也是文件,它也有自己的属性,关键就是目录的内容
foo.txt
)。dir
中有两个文件 file1.txt
和 file2.txt
,那么该目录中的目录项会记录如下信息: file1.txt
和 inode 号 123
file2.txt
和 inode 号 124
所以一个目录下不能建立同名文件,就是因为文件名和inode号要互为键值,互相能找到彼此/home/user/file1.txt
),操作系统会根据路径从根目录开始查找,逐级查找每个目录,直到找到目标文件的目录。目录的r本质就是是否允许我们读取目录的内容
目录的w,决定是否能新建文件,因为文件的新建最后一定要向当前所处的目录内容中写入文件名和inode的映射关系
/home/user/file.txt
时,操作系统会缓存 /home
、/home/user
等目录的 dentry,避免下次访问时重新查找这些目录。当用户或程序访问文件时,操作系统通常会按照以下路径结构来处理缓存:
文件访问流程
用户请求文件数据
|
解析文件路径
|
┌──────────────────┐
│ 目录项缓存(dentry cache)│ ← 如果存在,直接返回缓存数据
└──────────────────┘
|
查找 inode 信息
|
┌──────────────────┐
│ inode 缓存(inode cache) │ ← 如果存在,直接返回缓存数据
└──────────────────┘
|
读取文件数据
|
┌──────────────────┐
│ 页缓存(page cache) │ ← 如果存在,直接返回缓存数据
└──────────────────┘
|
读取磁盘数据块(如果不在缓存中)
|
┌──────────────────┐
│ 块缓存(block cache) │ ← 如果存在,直接返回缓存数据
└──────────────────┘