根据前面几章的学习,我们基本上掌握了文件系统和磁盘的一系列基本信息,从应用到磁盘整个的读写过程,以及虚拟文件系统和块设备层所起的承上启下的作用,最后到获取观察他们性能的一些指标信息。有了这些信息,我们再去分析有关磁盘的性能时,就会从容很多,还不了解相关信息的,请再去阅读一下吧。
1、系统I/O栈
在整个业务请求I/O数据落盘的过程中,数据需要先后调用虚拟文件系统的接口,再到块设备层对I/O请求进行整理、排序合并,最后才能写到磁盘中,这组成了整个系统的存储I/O栈。它几乎是整个系统中效率最慢的一层,为了提高其中的性能,所有才有了各种缓存机制。
针对文件系统,使用了页缓存、索引缓存、目录项缓存等,借助于内存的高效率,采用先写缓存再异步刷新写盘的方式,大幅提升文件系统的I/O效率。对内存缓存不熟悉的朋友可以再去看下内存篇系列文章。
而针对硬件设备,则采用缓冲的方式,使用缓冲区来缓存块设备的数据,同样可以提供效率。
那我们就根据这个思路来梳理一下整个过程中影响磁盘读写延迟的可能因素。
2、磁盘延迟变高
在系统操作时,感觉最明显的磁盘延迟就是系统发生卡顿,这就是我们之前提到的磁盘I/O指标响应时间,一般响应时间的计算公式为
响应时间 = 传输时间(来回)+ 请求队列时间 + 磁盘处理时间
我们对这个过程的每个可能影响因素逐个进行分析,通过这个过程,也给出了我们遇到类似问题的排查思路。
1、 ** 传输时间 **
,这个受限因素主要是网络,集中在传输介质、带宽、网卡、流量调度、网络拓扑、协议配置等等各个方面,这个话题的细节我们后面在网络篇展开再讲,欢迎关注等后续。
2、 ** 请求队列时间 ** ,在负载不高且硬件无故障时,请求队列的值应该是非常低的。那什么时候这个值会升高呢,我们假设几种情况,往回推导。
查看使用工具iostat -d -x 1,看avgqu-sz的值
root@node:~# iostat -d -x 1
Linux 4.15.0-58-generic (cs1anr01n02) 11/14/2025 _x86_64_ (48 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 1.05 0.00 1.04 0.00 9.60 18.40 0.00 3.95 0.29 3.95 1.58 0.16
sdb 0.00 0.04 0.26 203.44 10.18 1663.53 16.43 0.03 0.15 1.81 0.14 0.06 1.17
sdc 0.00 0.04 0.33 154.60 14.10 1250.00 16.32 0.02 0.15 2.00 0.15 0.07 1.08
nvme0n1 20.88 70.25 367.48 691.60 3127.79 6237.64 17.69 0.02 0.01 0.05 0.03 0.01 0.77
intelcas1-1 0.00 0.00 1.15 131.82 147.45 1763.82 28.75 0.02 0.13 0.79 0.12 0.07 0.86
intelcas1-2 0.00 0.00 1.56 116.54 147.79 1252.25 23.71 0.01 0.12 0.75 0.11 0.06 0.72
-
突然出现高并发 I/O:产生大量的进程同时发起读写请求(如数据库批量操作、大数据任务等),这时如果超出存储 IOPS / 吞吐量上限,就会出现队列堆积。我们需要 结合fio测试 的极限值来判断。
-
小 I/O 请求比较密集的负载:频繁的小文件读写(如日志写入、数据库随机查询等),单次的 I/O 处理非常快但是数量极多,这时就容易造成队列堆积。这是我们可以使用iostat工具来查看一下这几个值(
r/s 每秒读请求次数、w/s每秒写请求次数、rkB/s每秒读数据量、wkB/s每秒写数据量),然后根据计算公式 数据量除以次数
大体估算I/O请求的大小。 -
应用 I/O 模型比较低效:同步 IO 过多、未使用异步 IO,或者是频繁的进行文件打开 / 关闭操作,增加了 I/O 的请求开销。这个需要去看一下应用的信息,也可以通过 strace工具 进行调试诊断。
-
系统内部资源竞争:CPU、内存不足(如内存被占满导致缓存失效),或其他进程同时在用占用了大量 的I/O 资源,这也会导致目标 I/O 请求排队。这种需要及时 检测资源的使用率 情况。
3、 ** 磁盘处理时间 ** ,影响磁盘发挥最佳性能的因素主要有以下几种。
第一种,磁盘固件发生故障。
有可能出现坏道、读写错误等,导致重试和延迟。也有可能随着使用时间增长,磁盘本身性能下降。再就是机房环境(例如温度)、线缆等也会产生影响。
针对磁盘本身的问题,我们可以使用工具disktool或者smartctl在系统内快速检测一下。
例如使用命令 disktool show -l all ,快速看一下磁盘是否有error或者磁盘温度是否过高。
root@node:~# disktool show -l all
-- Controller Information --
+---------------+--------+------------+----------------+-------+--------------+
| controller_id | locate | enclosures | virtual_drives | disks | pci_path |
+---------------+--------+------------+----------------+-------+--------------+
| 0 | c0 | 1 | 1 | 2 | 0000:5e:00.0 |
| 1 | c1 | 2 | 2 | 12 | 0000:af:00.0 |
+---------------+--------+------------+----------------+-------+--------------+
-- Enclosure Information --
+--------------+--------+--------+---------------------------+-----------------+
| enclosure_id | locate | status | number_of_physical_drives | number_of_slots |
+--------------+--------+--------+---------------------------+-----------------+
| 8 | c1e8 | OK | 12 | 16 |
| 252 | c1e252 | OK | 0 | 8 |
+--------------+--------+--------+---------------------------+-----------------+
-- Virtual Drive Information --
+-------+--------+------------+----------+---------+------------------+
| vd_id | locate | raid_level | path | state | number_of_drives |
+-------+--------+------------+----------+---------+------------------+
| 0 | c1v0 | raid5 | /dev/sdb | optimal | 3 |
| 1 | c1v1 | raid5 | /dev/sdc | optimal | 3 |
+-------+--------+------------+----------+---------+------------------+
-- Physical Disk Information In Raid Model --
+-------+----------+----------+-----------+--------+--------+--------------------+------+--------------+---------+
| pd_id | p_locate | v_locate | interface | medium | state | sn | slot | error(m|o|p) | speed |
+-------+----------+----------+-----------+--------+--------+--------------------+------+--------------+---------+
| 8 | c0e252s0 | c0v0d8 | sata | ssd | online | BTYF01830HFC480CGN | 0 | 0|0|0 | 6.0Gb/s |
| 9 | c1e8s2 | c1v0d9 | sata | hdd | online | WKD20E4X | 2 | 0|0|0 | 6.0Gb/s |
| 10 | c1e8s4 | c1v0d10 | sata | hdd | online | WKD27F1X | 4 | 0|0|0 | 6.0Gb/s |
| 11 | c1e8s10 | c1v0d11 | sata | hdd | online | WKD28DDX | 10 | 0|0|0 | 6.0Gb/s |
| 12 | c1e8s6 | c1v0d12 | sata | hdd | online | WKD26G4X | 6 | 0|0|0 | 6.0Gb/s |
| 20 | c1e8s8 | c1v1d20 | sata | hdd | online | WKD26J5X | 8 | 0|0|0 | 6.0Gb/s |
+-------+----------+----------+-----------+--------+--------+--------------------+------+--------------+---------+
-- Nvme device Information --
+---------+--------------+--------------------+--------------+-------------+------------------+--------------+---------------------+
| name | path | sn | percent_used | temperature | critical_warning | media_errors | num_err_log_entries |
+---------+--------------+--------------------+--------------+-------------+------------------+--------------+---------------------+
| nvme0n1 | /dev/nvme0n1 | BTYF01830HFC480CGN | 5 | 43 | 0 | 0 | 0 |
+---------+--------------+--------------------+--------------+-------------+------------------+--------------+---------------------+
-- Disk Smart Error --
-- Disk sn: BTYF01830HFC480CGN, Assessment: PASS --
+-----+-----------------------+---------+-------------+-----+
| num | name | type | when_failed | raw |
+-----+-----------------------+---------+-------------+-----+
| 5 | reallocated_sector_ct | Old_age | - | |
+-----+-----------------------+---------+-------------+-----+
第二种,就是磁盘的调度算法配置不正常。 我们前面文章已经了解了几种调度算法(如CFQ、NOOP、Deadline),它们对不同类型的负载都有不同影响。
** none : ** 如果磁盘选择这种,一般就是不使用调度器,大部分用在直连SSD盘时,也就是避开文件系统的I/O。
** noop : ** 这种是I/O请求先入先出的队列,只做一些最基本的请求合并。
** CFQ : ** 这种是每个进程维护了一个 I/O 调度队列,完全公平的分配I/O请求。
** deadline : ** 这种是读和写的请求分别创建不同的 I/O
队列,这样读写性能会提高很多,同时确保达到最终期限(deadline)的请求被优先处理。这里注意高版本的Linux内核名字可能叫mq-deadline。
第三种,系统的选择和配置也会产生影响。 磁盘的写缓存策略(如透写、回写)也会影响性能。若使用raid,不同的raid选择都会产生影响。
1416

被折叠的 条评论
为什么被折叠?



