
前面的文章中,我们谈了文件系统和磁盘的相关信息,重点说了目录项、索引节点以及存储数据的逻辑块等,还说了虚拟文件系统以及它是如何承上启下的关联起各种各样的文件系统。
今天我们再详细的聊一下磁盘配合文件系统是如何进行工作的,以及在这个过程中有哪些指标能够说明磁盘工作的性能。
1、了解磁盘
这里先简要说明一下磁盘硬件的信息,以便帮助我们更好地理解下面的内容。磁盘一般分为机械盘和固态盘,两者速度差异很大,核心在于机械盘使用的是磁道寻址技术,在读写不连续数据扇区时,需要不断的调整磁头。
机械盘数据落盘的单位是扇区,最小512字节,为了读写效率,上层文件系统一般要将它们组成数据逻辑块来用。固态盘则不同,它的单位是页,最小4K或者8K,一个页能当一个数据逻辑块来用,也可以组成大页来用,当然大页得通过系统层或者存储层配置聚合。
磁盘又可以根据接口不同,分为IDE、SATA、SCSI、SAS等类型,最直观的就是在系统中看到的盘符名称不一样,例如常见的就是hda、sda。
有了这些基础信息,我们再进一步往下看磁盘到底是怎么跟系统进行交互的。
2、磁盘工作流程
在上面的文章链接中,我们用AI生成了一个结构图,这里我们拿过来再用一下,以帮助更好的理解。

根据这个图,我们很清晰的就可以了解到从 ** 应用层 ** → ** 系统接口 ** → ** 虚拟文件系统 ** → ** 各种文件系统
** → ** 块设备层→设备驱动→磁盘硬件 ** 的整个过程,其中我们重点说一下块设备层。
我们知道磁盘其实就是一个块设备,这个块设备层跟我们之前提到的虚拟文件系统有点类似,也是起到承上启下的作用,下面可以兼容各种类型的磁盘驱动,上面为文件系统提供统一的接口。同时,它还可以将文件系统发来的I/O请求做统一的安排,合并、排列等操作,将随机的、小规模的I/O请求变成顺序的、大规模的I/O请求,所以又被称作"I/O调度器"。
再进一步说下这个I/O调度器,一般Linux内核支持三种调度器算法(不同发行版可能名称不一样),另外再加一种不使用调度器,这样一共4种方案,不同的磁盘类型根据访问特性会用到不同的算法。
** none ** :如果磁盘选择这种,一般就是不使用调度器,大部分用在直连SSD盘时,也就是避开文件系统的I/O。
** noop ** :这种是I/O请求先入先出的队列,只做一些最基本的请求合并。
** CFQ ** :这种是每个进程维护了一个 I/O 调度队列,完全公平的分配I/O请求。
** deadline ** :这种是读和写的请求分别创建不同的 I/O
队列,这样读写性能会提高很多,同时确保达到最终期限(deadline)的请求被优先处理。这里注意高版本的Linux内核名字可能叫mq-deadline。
这几个算法在配置时可以组合灵活使用,也可以通过配置文件修改配置。例如这是一台高性能存储节点的配置。
bash
root@nede:~# cat /sys/block/nvme0n1/queue/scheduler
[none]
root@node:~# cat /sys/block/sda/queue/scheduler
noop [deadline] cfq
其中sda就是普通的ssd磁盘,nvme0n1是高性能存储盘,而且nvme0n1是直接连接存储系统绕开了系统的文件系统。
如果要修改的话,可以使用下面的方法。
bash
# 临时设置为 deadline
echo deadline > /sys/block/sda/queue/scheduler
#永久生效可以修改/etc/default/grub,保存后update-grub
#设置 scheduler 为 deadline
GRUB_CMDLINE_LINUX_DEFAULT="elevator=deadline"
有了这个块设备层,可以解决很多I/O请求的问题,提高了磁盘读写的性能,但是磁盘的速度相对于内存的速度还是差了很多,为了减少频繁的读写磁盘,所以才会出现各种缓存机制,例如buffer、cache、swap等,这一块不熟悉的可以再去看下内存篇系列文章。
3、性能指标
因为随着磁盘在实际业务中的使用,它的性能并不是固定的,有时会高有时也会低。在了解了磁盘的整个读写过程后,接下来我们再看一下哪些指标能够反映出磁盘的性能,并对它们做一下详细的解释。
1、使用率
这个指标衡量的是磁盘的忙碌程度,不是那个磁盘容量的使用率。例如使用率为60%,那说明在一个时间采集周期内有60%的时间在处理请求,还有40%是空闲状态。
查看这个指标可以使用命令 iostat -d -x 1 ,其中 %util 就是使用率。
bash
root@node:~# iostat -d -x 1
Linux 4.15.0-58-generic (cs1anr02n04) 11/13/2025 _x86_64_ (64 CPU)
Device: rrqm/s wrqm/s r/s w/s rkB/s wkB/s avgrq-sz avgqu-sz await r_await w_await svctm %util
sda 0.00 0.89 0.00 0.92 0.00 7.58 16.48 0.00 3.87 0.43 3.87 1.86 0.17
nvme6n1 0.00 0.03 16.49 96.75 211.33 1756.10 34.75 0.00 0.04 0.15 0.02 0.01 0.09
nvme7n1 0.00 0.04 2.24 64.91 72.99 1200.40 37.93 0.00 0.04 0.18 0.03 0.00 0.03
nvme5n1 0.00 0.04 0.14 52.87 11.22 730.40 27.98 0.00 0.04 0.57 0.04 0.00 0.01
nvme4n1 0.00 0.04 0.82 60.74 29.77 1509.10 50.00 0.00 0.05 0.23 0.05 0.01 0.04
nvme3n1 0.00 0.04 67.06 60.68 356.48 1265.74 25.40 0.01 0.06 0.09 0.03 0.01 0.19
nvme2n1 0.00 0.04 0.11 48.79 9.36 545.12 22.68 0.00 0.04 0.42 0.04 0.00 0.01
nvme0n1 0.00 0.04 5.17 91.90 168.14 2328.52 51.44 0.00 0.04 0.22 0.03 0.01 0.08
nvme1n1 0.00 0.04 8.66 84.76 258.53 2045.13 49.32 0.00 0.05 0.22 0.03 0.01 0.07
2、饱和度
当磁盘收到的请求太多,而自己能力无法处理时,这些I/O请求就会放在队列里,这个队列长度就是饱和度,所以这个值越低越好。如果饱和度提高,队列等待很长,直接表现就是读写延迟,系统卡顿。
指标体现就是 iostat 输出中的 avgqu-sz 。
3、IOPS
这个指标衡量的是磁盘处理请求的速度,例如存在大量小文件读写的系统重,iops一般要求要高。这里需要搞清楚的是,iops高并不一定说处理的数据量就多,有些系统可能都是大文件数据流,例如视频资源,对iops的要求就没那么高。
指标体现在 iostat 输出中的 r/s(读IOPS) 和 w/s(写IOPS) 。
4、吞吐量
这个指标衡量的就是刚才说的数据量了,它的单位一般都是每秒多少MB或者GB。
指标体现在 iostat 输出中的 rkB/s 和 wkB/s 。
5、响应时间
响应时间一般就是指发出请求到完成处理返回的时间。这里面最主要包含了队列等待时间和磁盘处理的时间。
指标体现在 iostat 中的 await 这个值。
除了上面提到的iostat这个工具,我们还可以使用pidstat、iotop等工具进一步观察进程级别的I/O使用情况。
这些指标基本涵盖了磁盘性能的情况,但要说明一点,这些指标并不是孤立的,而是相互体现和佐证的。