4、磁盘I/O性能分析:磁盘工作原理、I/O调度器、iostat与iotop实战、IOPS与吞吐量
磁盘I/O,说白了就是整个系统最慢的那一环。我见过太多应用,CPU和内存都闲得发慌,结果业务卡得不行,一查全是磁盘在拖后腿。今天咱们就把磁盘I/O这块彻底聊透。
4.1 磁盘工作原理:机械盘与SSD的差异
先说说机械硬盘(HDD)。它的核心结构其实很简单:盘片、磁头、马达。读数据时,磁头要移动到对应磁道(寻道时间),然后等盘片转到目标扇区(旋转延迟)。这两个动作,就是机械盘最慢的地方。
我在项目中遇到过一台数据库服务器,每秒查询量一上来,磁盘利用率直接飙到100%。后来发现是机械盘的随机读写性能太差,寻道时间占了大部分开销。换成SSD后,问题立刻缓解。
SSD就不一样了。它没有机械部件,靠闪存颗粒存储数据。随机读写性能比机械盘高出一个数量级。但SSD也有短板——写放大和寿命问题。频繁的小块写入,会让SSD的寿命快速消耗。
- HDD:顺序读写快,随机读写慢(寻道+旋转延迟)
- SSD:随机读写快,但存在写放大和磨损均衡问题
- HDD适合大文件顺序读写,SSD适合高并发随机I/O
4.2 I/O调度器:内核如何管理磁盘请求
Linux内核里有个东西叫I/O调度器。它的任务很简单:把一堆乱糟糟的I/O请求排好队,尽量让磁盘干活更高效。
常用的调度器有几种:
- CFQ(完全公平队列):每个进程一个队列,公平分配时间片。适合桌面环境,但服务器场景下延迟偏高。
- Deadline:给每个请求设一个截止时间,优先处理快超时的请求。能有效避免某个请求被饿死。
- NOOP:什么都不做,直接按先进先出处理。适合SSD,因为SSD不需要寻道优化。
- Kyber:基于延迟的调度器,自动调整队列深度,适合NVMe SSD。
我个人习惯在数据库服务器上用Deadline。为什么?因为数据库对延迟敏感,Deadline能保证写请求不会等太久。我曾经调过一台MySQL服务器,从CFQ换成Deadline后,写延迟直接降了30%。
cat /sys/block/sda/queue/scheduler,临时切换用 echo deadline > /sys/block/sda/queue/scheduler。永久修改要改grub参数。
4.3 iostat实战:读懂磁盘性能指标
iostat是我排查磁盘问题时的第一把刀。它的输出信息很丰富,但很多人只盯着%util看,其实不够。
先看一个典型输出:
$ iostat -x 1 5
Device r/s w/s rkB/s wkB/s await svctm %util
sda 120 80 4800 3200 12.5 4.2 85.0
几个关键指标:
- r/s, w/s:每秒读写请求数。这个值直接反映I/O并发度。
- rkB/s, wkB/s:每秒读写数据量。结合r/s可以算出平均I/O大小。
- await:I/O请求的平均等待时间(包括排队和服务时间)。这个值超过20ms就要警惕了。
- svctm:I/O请求的实际服务时间。机械盘一般在5-10ms,SSD在0.1-1ms。
- %util:磁盘忙闲比例。但要注意,%util到100%不代表磁盘真的满了,可能是队列深度不够。
我记得有一次帮客户排查,%util只有60%,但业务已经卡得不行。后来发现是队列深度太小,请求都在排队。调大队列深度后,%util上去了,延迟反而降了。
4.4 iotop实战:定位哪个进程在吃I/O
iostat能告诉你磁盘忙不忙,但谁在搞事?这时候就要用iotop了。
iotop的原理很简单:它监控每个进程的I/O读写速率,然后按大小排序。用法也很直接:
$ iotop -oP
Total DISK READ : 0.00 B/s | Total DISK WRITE : 15.00 M/s
PID PRIO DISK READ DISK WRITE COMMAND
1234 be/4 0.00 B/s 12.00 M/s mysqld
5678 be/4 0.00 B/s 3.00 M/s java
参数说明:
-o:只显示有I/O活动的进程-P:只显示进程,不显示线程-a:显示累计I/O量
实战中,我经常这样用:先跑iostat发现磁盘压力大,然后立刻开iotop看是哪个进程在写。有一次发现是日志收集进程在疯狂写磁盘,把数据库的I/O都抢走了。调整日志级别后,问题解决。
pidstat -d 1替代,效果类似。
4.5 IOPS与吞吐量:两个容易混淆的概念
IOPS和吞吐量,很多人混着用。其实它们描述的是两个维度。
IOPS:每秒能处理多少个I/O请求。它衡量的是并发处理能力。随机读写场景下,IOPS是关键指标。
吞吐量:每秒能传输多少数据。它衡量的是带宽。顺序读写场景下,吞吐量是关键指标。
举个例子:机械盘的IOPS大概在100-200,但顺序吞吐量能到200MB/s。SSD的IOPS能到几万甚至几十万,但吞吐量可能只有500MB/s。你想想看,如果业务是大量小文件随机读写,IOPS就是瓶颈;如果是大文件顺序拷贝,吞吐量才是关键。
我在项目中遇到过一台文件服务器,用户抱怨上传慢。一查,IOPS只有80,但吞吐量还有富余。后来发现是文件碎片太多,导致随机读写性能下降。整理碎片后,IOPS翻了一倍。
| 场景 | 关注指标 | 典型值(HDD) | 典型值(SSD) |
|---|---|---|---|
| 数据库OLTP | IOPS | 100-200 | 10,000-100,000 |
| 视频流媒体 | 吞吐量 | 100-200 MB/s | 300-500 MB/s |
| 日志写入 | IOPS + 吞吐量 | 50-100 IOPS | 5,000-20,000 IOPS |
4.6 知识体系图:磁盘I/O分析全景
下面这张图把磁盘I/O分析的核心逻辑串起来了。从硬件原理到调度策略,再到监控工具和关键指标,一条线走通。
嗯,到这里磁盘I/O这块就聊得差不多了。记住一句话:磁盘性能问题,80%都能通过iostat+iotop的组合拳定位出来。剩下的20%,需要结合业务逻辑和文件系统特性去深挖。
公众号:蓝海资料掘金营,微信deep3321