磁盘IO性能分析
目录
一、IO
性能分析
1.1 IO
性能、顺序访问和随机访问
如果去看硬盘厂商的性能报告,通常你会看到两个指标;
- 一个是响应时间(
Response Time
); - 另一个叫作数据传输率(
Data Transfer Rate
),数据传输率也称吞吐率。
1.1.1 数据传输率
我们先来看一看后面这个指标,数据传输率。
我们现在常用的硬盘有两种;
- 一种是
HDD
(Hard Disk Drive
)硬盘,也就是我们常说的机械硬盘;现在的HDD
硬盘,用的是SATA 3.0
的接口; - 另一种是
SSD
(Solid State Drive
)硬盘,一般也被叫作固态硬盘;而SSD
硬盘呢,通常会用两种接口:- 一部分用的也是
SATA 3.0
的接口; - 另一部分呢,用的是
PCI Express
的接口。
- 一部分用的也是
现在我们常用的SATA 3.0
的接口,带宽是6Gb/s
;这里的b
是比特,这个带宽相当于每秒可以传输600MB
的数据。
而我们日常用的HDD
硬盘的数据传输率,差不多在100~200MB/s
左右。比如:

1.1.2 响应时间
除了数据传输率这个吞吐率指标,另一个我们关心的指标响应时间,其实也可以在AS SSD
的测试结果里面看到,就是这里面的Acc.Time
指标。
这个指标,其实就是程序发起一个硬盘的写入请求,直到这个请求返回的时间。
可以看到,在上面的SSD
硬盘上,大概时间都是在几十微秒这个级别。
如果你去测试一块HDD
的硬盘,通常会在几毫秒到十几毫秒这个级别。这个性能的差异,就不是10
倍了,而是在几十倍,乃至几百倍。
光看响应时间和吞吐率这两个指标,似乎我们的硬盘性能很不错。即使是廉价的HDD
硬盘,接收一个来自CPU
的请求,也能够在几毫秒时间返回。一秒钟能够传输的数据,也有200MB
左右。你想一想,我们平时往数据库里写入一条记录,也就是1KB
左右的大小。我们拿200MB
去除以1KB
,那差不多每秒钟可以插入20
万条数据呢。但是这个计算出来的数字,似乎和我们日常的经验不符合啊?这又是为什么呢?
答案就来自于硬盘的读写。在顺序读写和随机读写的情况下,硬盘的性能是完全不同的。
我们回头看一下上面的AS SSD
的性能指标。你会看到,里面有一个4K
的指标。这个指标是什么意思呢?它其实就是我们的程序,去随机读取磁盘上某一个4KB
大小的数据,一秒之内可以读取到多少数据。
我们拿这个36MB/s
和一次读取4KB
的数据算一下。
36MB / 4KB = 9000
也就是说,一秒之内,这块SSD
硬盘可以随机读取9000
次的4KB
的数据。如果是写入的话呢,会更多一些65MB
/4KB
差不多是1.6
万多次。
1.1.3 IOPS
这个每秒读写的次数,我们称之为IOPS
,也就是每秒输入输出操作的次数。事实上,比起响应时间,我们更关注IOPS
这个性能指标。
IOPS
和DTR
(Data Transfer Rate
,数据传输率)才是输入输出性能的核心指标。
IOPS
可细分为如下几个指标:
Toatal IOPS
:混合读写和顺序随机I/O
负载情况下的磁盘IOPS
,这个与实际I/O
情况最为相符,大多数应用关注此指标;Random Read IOPS
:100%
随机读负载情况下的IOPS
;Random Write IOPS
:100%
随机写负载情况下的IOPS
;Sequential Read IOPS
:100%
顺序读负载情况下的IOPS
;Sequential Write IOPS
:100%
顺序写负载情况下的IOPS
。
我们在实际的应用开发当中,对于数据的访问,更多的是随机读写,而不是顺序读写。我们平时所说的服务器承受的并发,其实是在说,会有很多个不同的进程和请求来访问服务器。自然,它们在硬盘上访问的数据,是很难顺序放在一起的。这种情况下,随机读写的IOPS
才是服务器性能的核心指标。
好了,回到我们引出IOPS
这个问题的HDD
硬盘,那一块HDD
硬盘能够承受的IOPS
是多少呢?
HDD
硬盘的IOPS
通常也就在160
左右,而SSD
的IOPS
大约在10,000-75,000
之间,取决于具体的SSD
和它的工作负载。
1.2 如何定位IO_WAIT
对于上图那款SSD
硬盘,IOPS
也就是在1.6
万左右。而我们的CPU
的主频通常在2GHz
以上,也就是每秒可以做20
亿次操作。
即使CPU
向硬盘发起一条读写指令,需要很多个时钟周期,一秒钟CPU
能够执行的指令数,和我们硬盘能够进行的操作数,也有好几个数量级的差异。
这也是为什么,我们在应用开发的时候往往会说性能瓶颈在I/O
上。因为很多时候,CPU
指令发出去之后,不得不去等我们的I/O
操作完成,才能进行下一步的操作。
那么,在实际遇到服务端程序的性能问题的时候,我们怎么知道这个问题是不是来自于CPU
等I/O
来完成操作呢?
别着急,我们接下来我们以我们测试环境遇到的IO
问题为例,就通过top
和iostat
这些命令,一起来看看CPU
到底有没有在等待io
操作。
1.2.1 top
在Linux
下经常会用top
去看服务的负载,也就是load average
。load average
(负载平均值)是一个重要的性能指标,它反映了系统在过去1分钟、5分钟和15分钟内的平均负载情况。
1.2.1.1 load average
load average
的三个值通常显示在任务栏的第一行中:
- 第一个值 (1分钟内的平均负载):这个值表示最近1分钟内正在运行和等待运行的进程的平均数量;如果这个值持续高于系统的
CPU
核心数(例如,如果你有4核CPU
,1分钟平均负载超过4),则系统可能会感觉到响应变慢; - 第二个值 (5分钟内的平均负载):这个值显示了最近5分钟内的平均负载情况,它可以帮助你观察到系统负载的长期趋势;
- 第三个值 (15分钟内的平均负载):这个值是最近15分钟内的平均负载情况,通常用来判断系统负载的趋势和变化;
通常来说,如果load average
长期超过系统的CPU
核心数(尤其是1分钟和5分钟的值),系统可能会感到卡顿或响应变慢,这时候需要进一步检查系统的资源使用情况和可能的性能瓶颈。
通过上图看到load average
显示高于系统的核心数(96
核),并且持续较长时间。
此外我们机器内存251G
,目前剩余只有3G
左右,导致服务器输入命令存在严重卡顿问题。
1.2.1.2 各个参数
此外,我们可以通过数字键1调出CPU
的资源使用情况。
在top
命令的输出结果里面,有一行是以%CPU
开头的。下面是各个百分比的含义:
-
us(userspace)
:用户空间的程序所消耗的CPU
时间百分比,这表示正在运行的用户进程(非内核进程)所使用的CPU
时间; -
sy(system)
:内核空间的程序所消耗的CPU
时间百分比。这表示正在运行的内核进程所使用的CPU
时间,如系统调用、中断处理等; -
ni(nice)
:通过nice
命令设置了较低优先级的进程所消耗的CPU
时间百分比;在这个报告中,该项值为0.1
; -
id(idle)
:空闲状态的CPU
时间百分比,这表示CPU
未被任何任务占用的时间; -
wa(waiting)
:等待I/O
完成的CPU
时间百分比,这表示CPU
在等待磁盘或其他I/O
设备完成操作时所使用的时间; -
hi(hardwareinterrupts)
:硬件中断所消耗的CPU
时间百分比。这表示CPU
在处理硬件中断请求时所使用的时间; -
si(softwareinterrupts)
:软件中断所消耗的CPU
时间百分比。这表示CPU
在处理软件中断请求时所使用的时间; -
st(stealtime)
:当运行在虚拟化环境中的虚拟机被物理主机偷取CPU
时间时所消耗的CPU
时间百分比;
这一行里,有一个叫作wa
的指标,这个指标就代表着iowait
,也就是CPU
等待IO
完成操作花费的时间占 CPU
的百分比。如果wa
值很高,说明系统中有大量的I/O
操作占用了CPU
时间,导致CPU
无法及时处理其他任务,从而影响系统性能。
当系统中有大量的进程在运行时,只有一小部分进程是I/O
密集型进程,即依赖磁盘I/O
的进程,而其余进程主要是CPU
密集型进程,即需要大量的计算资源的进程。因此,在这种情况下,即使磁盘已经达到了最大的吞吐量,wa
指标值也可能很低,因为系统中大多数进程并不需要等待磁盘I/O
的完成。
下一次,当你自己的服务器遇到性能瓶颈,load
很大的时候,你就可以通过top
看一看这个指标。
知道了iowait
很大,那么我们就要去看一看,实际的I/O
操作情况是什么样的。这个时候,你就可以去用iostat
这个命令了。
1.2.2 iostat
iotop
命令看到实际的硬盘读写情况,这个命令里,不仅有iowait
这个CPU
等待时间的百分比,还有一些更加具体的指标了,并且它还是按照你机器上安装的多块不同的硬盘划分的。
iostat
查看系统IO
指标:
iostat -dx 1

其中:
Device
:磁盘设备名称;rrqm/s
:每秒钟发起的读请求被合并为更大的请求的数量;wrqm/s
:每秒钟发起的写请求被合并为更大的请求的数量;r/s
:每秒钟发起的读请求的数量;w/s
:每秒钟发起的写请求的数量;rkB/s
:每秒钟读取的数据量,单位为KB
;wkB/s
:每秒钟写入的数据量,单位为KB
;avgrq-sz
:平均请求大小,单位为扇区大小(一般为512
字节);avgqu-sz
:平均请求队列长度;await
:平均请求等待时间,单位为毫秒;r_await
:平均读请求等待时间,单位为毫秒;w_await
:平均写请求等待时间,单位为毫秒;svctm
:平均请求处理时间,单位为毫秒;%util
:磁盘处理I/O
的时间百分比,即设备正在处理请求的时间占总时间的百分比;
其中重点关注:
r/s + w/s
就是IOPS
,即每秒读写次数;rkB/s + wkB/s
就是吞吐量,即每秒读写数据量;对应着我们的数据传输率的指标;r_await + w_await
,就是响应时间,即指I/O
请求从发出到收到响应的间隔时间;
知道实际硬盘读写的IOPS
、数据传输率的指标,我们基本上可以判断出,机器的性能是不是卡在I/O
上了。
如果util
字段显示为100%
,表示磁盘正在以最大速度处理请求,也就是说磁盘已经达到了最大的吞吐量。这意味着磁盘已经成为系统中的瓶颈,无法再处理更多的I/O
请求。这种情况下,应该考虑增加更多的磁盘或者使用更快的存储设备来提高系统性能。同时,也可以尝试优化应用程序的I/O
操作,减少对磁盘的访问,从而降低磁盘的负载。
此前,我们提到过我们机器内存251G
,只剩下3G
左右,导致服务器输入命令存在严重卡顿问题。后面停止到一些进程后,服务运行正常,内存占用如下;
[root@kylin ~]$ free -h -m
total used free shared buff/cache available
Mem: 251G 116G 13G 4.8G 121G 128G
Swap: 0B 0B 0B
再次通过iostat
查看系统IO
指标:

可以看到此时的wkB/s
可以达到上百MB
,远高于服务器卡顿时的10~20MB
。
1.2.3 iotop
如果机器的性能卡在了I/O
上,通过iotop
这个命令,可以看到具体是哪一个进程实际占用了大量I/O
;
sudo iotop -o -b | while read -r line;do echo "$line" | grep 'Actual DISKWRITE';done
sudo iotop -oP

其中:
-o
:only show processes or threads actually doing I/O
;-P
:only show processes, not all threads
;-k
:use kilobytes instead of a human friendly unit
;-b
:non-interactive mode
;
前两行分别表示,进程的磁盘读写大小总数和磁盘真实的读写大小总数。因为缓存、缓冲区、I/O
合并等因素的影响,它们可能并不相等。
如果进程IO
等待时间过长(比如80%
),大概率磁盘IO
到了瓶颈,来不及处理。
关注一下Actual DISK WRITE
这个参数,可以参考4K
指标的值,如果超过这个值,这台机器的磁盘I/O
基本就满了;可以结合夜莺看一下I/O
是否满了。
1.3 慢SQL
有时候存在数据库慢SQL
导致其他进程请求超时,PG
慢SQL
查询;
select *
from pg_stat_activity
where state <> 'idle'
and now() - query_start > interval '1s'
order by query_start;
可以看到是否存在慢SQL
,以及该SQL
是否一次请求了万级别以上的数据。
二、jbd2
进程导致磁盘IO
高
在服务器发现业务进程偶尔响应超时,排查后发现磁盘的sdb util
接近100%
;
但是磁盘吞吐量并不高,IO
流量只有6MB
左右,主要是由w/s
导致,也就是写入的IOPS
高,这种情况一般就是进程的sync
操作密集。
2.1 iotop
通过iotop
来查看是哪个进程,显示为jbd2
;

查阅一些资料后,了解到jbd2
进程负责ext4
这种日志文件系统的日志提交操作,关于jbd2
引起磁盘IO
高,网上也有很多类似案例,总结起来有几方面原因:
- 系统
bug
; ext4
文件系统的相关配置问题;- 其他进程的
fsync
,sync
操作过于频繁;
首先排除系统bug
因素,网络上反馈的问题在很低的版本,我们生产环境为Centos 7+
,其次,查阅了/proc/mounts
等信息,发现文件系统配置参数与其他环境差异不大,按照网上提供的关闭某些特性,降低commit
频率等理论来说会有效果,但需要重新mount
磁盘,相关组件都要重启,并且这看起来并非根本原因。
2.2 sync
尝试分析sync
调用,使用sysdig
最方便,但现场环境安装很麻烦,因此开启几个内核trace
查看:
在jbd2
执行flush
时输出日志
echo 1 > /sys/kernel/debug/tracing/events/jbd2/jbd2_commit_flushing/enable
在任意进程执行sync
时输出日志:
echo 1 > /sys/kernel/debug/tracing/events/ext4/ext4_sync_file_enter/enable
然后观察日志输出:
cat /sys/kernel/debug/tracing/trace_pipe
输出信息如下:

可以看到jbd2
和 92350
进程有大量的sync
,瞬间刷出大量日志,因此基本确定92350
进程。
ps
看一下是哪个任务导致的:
ps -efL | grep 92350
-L
或-T
参数显示线程id
,ps
获取到pid
和程序路径后,发现是XX
进程,很让人疑惑,XX
怎么会大量sync
呢,trace
一下他在做什么。
2.3 strace
亲爱的读者和支持者们,自动博客加入了打赏功能,陆陆续续收到了各位老铁的打赏。在此,我想由衷地感谢每一位对我们博客的支持和打赏。你们的慷慨与支持,是我们前行的动力与源泉。
日期 | 姓名 | 金额 |
---|---|---|
2023-09-06 | *源 | 19 |
2023-09-11 | *朝科 | 88 |
2023-09-21 | *号 | 5 |
2023-09-16 | *真 | 60 |
2023-10-26 | *通 | 9.9 |
2023-11-04 | *慎 | 0.66 |
2023-11-24 | *恩 | 0.01 |
2023-12-30 | I*B | 1 |
2024-01-28 | *兴 | 20 |
2024-02-01 | QYing | 20 |
2024-02-11 | *督 | 6 |
2024-02-18 | 一*x | 1 |
2024-02-20 | c*l | 18.88 |
2024-01-01 | *I | 5 |
2024-04-08 | *程 | 150 |
2024-04-18 | *超 | 20 |
2024-04-26 | .*V | 30 |
2024-05-08 | D*W | 5 |
2024-05-29 | *辉 | 20 |
2024-05-30 | *雄 | 10 |
2024-06-08 | *: | 10 |
2024-06-23 | 小狮子 | 666 |
2024-06-28 | *s | 6.66 |
2024-06-29 | *炼 | 1 |
2024-06-30 | *! | 1 |
2024-07-08 | *方 | 20 |
2024-07-18 | A*1 | 6.66 |
2024-07-31 | *北 | 12 |
2024-08-13 | *基 | 1 |
2024-08-23 | n*s | 2 |
2024-09-02 | *源 | 50 |
2024-09-04 | *J | 2 |
2024-09-06 | *强 | 8.8 |
2024-09-09 | *波 | 1 |
2024-09-10 | *口 | 1 |
2024-09-10 | *波 | 1 |
2024-09-12 | *波 | 10 |
2024-09-18 | *明 | 1.68 |
2024-09-26 | B*h | 10 |
2024-09-30 | 岁 | 10 |
2024-10-02 | M*i | 1 |
2024-10-14 | *朋 | 10 |
2024-10-22 | *海 | 10 |
2024-10-23 | *南 | 10 |
2024-10-26 | *节 | 6.66 |
2024-10-27 | *o | 5 |
2024-10-28 | W*F | 6.66 |
2024-10-29 | R*n | 6.66 |
2024-11-02 | *球 | 6 |
2024-11-021 | *鑫 | 6.66 |
2024-11-25 | *沙 | 5 |
2024-11-29 | C*n | 2.88 |

【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
2018-08-03 集成学习值Adaboost算法原理和代码小结(转载)
2018-08-03 集成学习原理小结(转载)
2018-08-03 2019阿里校招测评题,光明小学完全图最短路径问题(python实现)