Linux磁盘IO性能监控与排查实战指南:从iostat到fio

📅 2026/8/12 10:48:19
Linux磁盘IO性能监控与排查实战指南:从iostat到fio
1. 项目概述为什么我们需要关注磁盘IO在Linux服务器运维、性能调优甚至是日常开发排查线上问题的过程中磁盘IOInput/Output输入/输出性能往往是那个最容易被忽视却又在关键时刻“卡脖子”的关键因素。你可能遇到过这样的场景应用响应突然变慢CPU和内存使用率看起来都挺正常但系统就是“卡顿”得不行。或者数据库查询耗时飙升前端页面加载缓慢一通排查下来最后发现瓶颈竟然在磁盘读写上。这时候如果不会查看和分析磁盘IO使用情况就像医生不会看X光片只能干着急。“linux查看磁盘io使用情况”这个标题看似简单背后却涵盖了从基础监控到深度性能分析的一整套方法论。它不仅仅是敲几个命令看看数字那么简单更重要的是理解这些数字背后的含义你的磁盘是“闲得发慌”还是“忙到冒烟”是顺序读写还是随机读写占主导IO延迟有多高有没有进程在“疯狂”读写磁盘搞清楚这些才能对症下药无论是优化应用代码、调整文件系统参数、升级硬件还是做架构层面的拆分都有了科学的依据。对于系统管理员、运维工程师、后端开发者乃至任何需要与服务器打交道的技术人员来说这都是必须掌握的核心技能。2. 核心工具与命令全解析Linux生态提供了从简单到复杂、从实时到历史记录的一系列工具来满足不同场景下的IO监控需求。我们可以把它们分为几个层次实时查看、进程级监控、历史统计和性能压测。2.1 实时监控利器iostatiostat可能是最常用、信息最全面的磁盘IO实时监控工具它属于sysstat工具包。它的强大之处在于不仅能看磁盘还能看CPU并且提供了丰富的速率和延迟指标。安装与基础使用大多数Linux发行版默认没有安装sysstat需要手动安装# CentOS/RHEL/Fedora sudo yum install sysstat # Debian/Ubuntu sudo apt-get install sysstat安装后最简单的用法是iostat但它默认显示的是自系统启动以来的平均值对实时监控意义不大。我们更常用的是带时间间隔的用法iostat -dx 2 5这个命令的含义是以-d显示设备磁盘统计信息-x显示扩展统计信息这是关键每2秒刷新一次总共刷新5次后退出。关键指标解读执行命令后你会看到类似下面的输出这里以sda设备为例Device r/s w/s rkB/s wkB/s rrqm/s wrqm/s %rrqm %wrqm r_await w_await aqu-sz rareq-sz wareq-sz svctm %util sda 5.20 3.10 256.00 128.00 0.00 0.00 0.00 0.00 1.20 2.50 0.05 49.23 41.29 0.80 0.66这些指标乍一看很多但我们可以分组理解吞吐量Throughputr/s,w/s每秒的读、写请求次数IOPS。这是衡量磁盘处理能力的关键。rkB/s,wkB/s每秒读、写的数据量KB。这反映了数据流量的大小。队列与合并rrqm/s,wrqm/s每秒被合并的读、写请求数。合并相邻的IO请求能提升效率。%rrqm,%wrqm被合并的读、写请求百分比。比例高通常是好事说明IO模式比较连续。延迟Latencyr_await,w_await读、写请求的平均等待时间毫秒。这是最关键的体验指标直接决定了应用程序感受到的“快慢”。通常机械硬盘应在10ms以内SSD应在1ms以内。如果这个值持续很高说明磁盘响应慢。aqu-sz平均请求队列长度。如果这个值持续大于1说明IO请求经常需要排队。请求大小rareq-sz,wareq-sz读、写请求的平均大小扇区通常1扇区512字节。小文件随机读写会导致这个值很小。利用率与繁忙度svctm平均每次IO请求的服务时间毫秒。这个值在单磁盘上接近物理极限如机械盘寻道时间。%util设备带宽利用率百分比。这是最经典的“磁盘忙不忙”的指标。但要注意对于SSD或RAID阵列由于并行处理能力即使%util达到100%也不一定意味着饱和需要结合r_await/w_await和aqu-sz一起看。实操心得不要孤立地看%util。一个%util接近100%但r_await很低如1ms的SSD可能依然游刃有余。而一个%util只有70%但r_await高达几十毫秒的机械硬盘很可能已经遇到了瓶颈比如磁头频繁寻道。我的习惯是先看r_await/w_await判断用户体验再看%util和aqu-sz判断设备压力最后用r/s/w/s和rkB/s/wkB/s分析负载类型。2.2 进程级IO追踪iotop与pidstat知道了磁盘忙下一步就是找出“谁”在忙。iostat告诉我们设备层面的情况而iotop和pidstat则能深入到进程级别。iotop交互式进程IO监控iotop类似于top命令但专注于IO。它可以实时显示每个进程的读写速率和累积IO量。sudo iotop运行后你会看到一个动态刷新的界面。关键列包括TID/PID: 线程/进程ID。PRIO: IO优先级。USER: 进程所有者。DISK READ,DISK WRITE: 实时读写速率。SWAPIN,IO:IO列表示进程等待IO的时间百分比是判断进程是否被IO阻塞的直观指标。你可以按o键只显示正在产生IO的进程按p键显示线程信息按a键显示累积IO量。这对于快速定位某个时间点疯狂读写磁盘的“元凶”非常有效。pidstat更详细的进程IO统计pidstat是sysstat包的另一利器它能提供更结构化、更详细的进程级IO报告并且方便记录和后期分析。# 查看所有进程的IO统计每秒刷新一次共5次 pidstat -d 1 5输出中kB_rd/s和kB_wr/s分别表示进程每秒读、写的千字节数kB_ccwr/s表示因任务取消而写入磁盘的数据量。结合-p参数可以监控特定进程结合-t参数可以查看线程信息。注意事项iotop需要内核支持通常已启用且需要root权限。在某些最小化安装的系统或容器内可能无法使用。pidstat则更为通用和脚本友好。2.3 系统级综合视图vmstat与sar有时候我们需要在一个更宏观的视角下看IO理解IO与系统其他资源如CPU、内存、上下文切换的关联。vmstat系统资源概览vmstat命令提供关于进程、内存、分页、块IO、陷阱和CPU活动的信息。vmstat 1关注bi每秒从块设备接收的块数和bo每秒发送到块设备的块数块大小通常为1KB。这两个值给出了系统级别的块IO吞吐量概览。如果它们持续很高结合waCPU等待IO的时间百分比也很高那就明确指示系统存在IO瓶颈。wa值如果长期大于5%就需要警惕了。sar历史数据回溯iostat和vmstat看实时那历史性能数据怎么看这就要用到sarSystem Activity Reporter它同样是sysstat包的一部分。sar守护进程会定期收集系统性能数据默认保存一段时间通常是一个月。# 查看当天磁盘设备的统计信息 sar -d # 查看指定日期的数据如查看昨天下午2点到3点的数据 sar -d -f /var/log/sa/saXX -s 14:00:00 -e 15:00:00 # XX是日期 # 查看CPU的IO等待时间历史 sar -usar -d的输出字段与iostat -dx类似但它是历史数据非常适合用于事后分析性能问题比如排查“昨天下午3点系统为什么慢”。2.4 进阶性能剖析blktrace与fio当你通过基础工具定位到大概的IO问题后可能需要更底层的工具进行深度剖析或者需要主动测试磁盘的极限性能。blktrace块层IO追踪blktrace是一个强大的工具它可以追踪一个IO请求从块设备层Block Layer下发到最终完成的全生命周期生成非常详细的跟踪日志。配合blkparse和btt工具可以分析出IO在每一个阶段如Q2C进入队列到被驱动处理C2I驱动处理到硬件中断所花费的时间是诊断复杂IO延迟问题的“手术刀”。# 对设备sda进行追踪持续10秒 sudo blktrace -d /dev/sda -w 10 # 解析生成的跟踪文件 blkparse -i sda -d sda.bin # 使用btt进行聚合分析 btt -i sda.bin这个工具相对复杂输出信息量大通常用于内核开发者或存储工程师进行极端情况下的问题诊断。fio灵活的IO压力测试fioFlexible I/O Tester不是监控工具而是性能测试工具。当你想知道你的磁盘或文件系统在特定负载模式如随机读、顺序写、混合读写下的极限性能IOPS、带宽、延迟时fio是标准选择。你可以用它来基准测试新硬盘或者模拟生产环境的IO模型来验证系统能力。# 一个简单的随机读测试示例 fio --namerandread --ioenginelibaio --iodepth32 --rwrandread --bs4k --direct1 --size1G --numjobs4 --runtime60 --time_based --group_reporting这个命令会启动4个线程每个线程进行4KB随机读队列深度32持续60秒并使用直接IO绕过缓存。测试结束后fio会给出详细的IOPS、带宽和延迟分布报告如延迟的百分比clat。实操心得fio的参数组合千变万化务必根据你的测试目标来设计。--direct1和--iodepth是关键参数前者避免操作系统缓存影响真实测磁盘性能后者模拟并发压力。测试前最好在目标磁盘上创建一个独立的测试文件避免影响生产数据。3. 实战场景分析与排查思路掌握了工具我们来看几个典型的实战场景如何串联使用这些工具进行问题排查。3.1 场景一应用响应变慢疑似IO瓶颈现象Web应用接口响应时间从平均50ms飙升到2s以上。登录服务器查看CPU使用率不高~30%内存充足但感觉系统“很卡”。排查步骤快速定位首先运行iostat -dx 2。发现sdb磁盘的%util持续在95%以上w_await高达150mswkB/s也很高。初步判断是sdb的写入压力极大导致高延迟。找出元凶保持iostat运行另开一个终端运行sudo iotop。很快发现一个名为data_backup.sh的脚本进程及其mysqldump子进程的DISK WRITE列数值极高IO列也接近100%。确认是备份任务在全量导出数据库大量写盘。评估影响运行vmstat 1观察到waCPU IO等待值在40%左右波动bo块写出值很大。这解释了为什么CPU不忙但系统卡——CPU都在等IO完成。制定策略与业务方确认该备份任务可以调整。临时方案通过ionice或cgroup限制备份进程的IO优先级。长期方案将备份任务调度到业务低峰期或使用具有从库进行备份避免影响主库性能。3.2 场景二数据库查询性能周期性下降现象MySQL数据库在每天固定时间如凌晨查询变慢但该时段并无业务高峰。排查步骤历史数据分析由于问题是周期性的首先使用历史数据工具。运行sar -d -f /var/log/sa/saXXXX为问题发生日期查看对应时间段的磁盘统计数据。发现sda磁盘的rkB/s和r/s在问题时段有规律性尖峰%util和r_await也随之飙升。关联进程分析检查该时间点的计划任务crontab -l和系统日志grep相关时间点的/var/log/messages或journalctl。发现有一个定时的日志分析任务启动该任务需要顺序扫描大量日志文件。根源分析日志分析任务是顺序读本应很快。但进一步用iostat -dx观察发现rareq-sz读请求平均大小很小只有几KB。这说明虽然是顺序读文件但应用程序可能是某个脚本或工具是以非常小的块如fread小缓冲区进行读取的导致物理上虽然是顺序访问但在块设备层却产生了大量的IO请求高IOPS拖慢了同时进行的数据库随机读请求因为磁头要频繁在日志文件和数据库文件间移动。解决方案优化日志分析任务的读取逻辑使用更大的缓冲区例如从4K调整为64K或128K减少IOPS。或者将日志文件放在与数据库不同的物理磁盘上实现IO隔离。3.3 场景三评估SSD替换机械盘的效果现象计划将数据库服务器的存储从SATA机械硬盘升级为NVMe SSD需要量化评估性能提升。排查步骤基准测试设计使用fio设计测试用例模拟数据库的典型负载。通常包括随机读模拟索引查找。--rwrandread --bs4k --iodepth32随机写模拟更新/插入。--rwrandwrite --bs4k --iodepth32顺序读/写模拟全表扫描或备份。--rwread/write --bs128k --iodepth8混合读写模拟真实负载。--rwrandrw --rwmixread70 --bs4k --iodepth32执行测试分别在旧机械盘和新SSD上使用相同的fio配置文件运行测试。关键点确保测试文件足够大远大于系统缓存并使用--direct1绕过页面缓存测试真实磁盘性能。使用--group_reporting查看聚合报告。指标对比重点关注以下指标IOPS随机读写测试结果。机械盘可能只有几百而NVMe SSD可达数十万甚至百万。带宽顺序读写测试结果。机械盘约100-200 MB/sNVMe SSD可达数GB/s。延迟clat完成延迟的百分比特别是clat percentiles中的99.00%或99.90%值。机械盘的尾延迟高百分位延迟可能高达几十毫秒而SSD可以稳定在几百微秒到几毫秒。延迟的稳定性和降低对数据库事务性能提升至关重要。生成报告将两次测试的fio输出结果保存并提取关键指标做成表格对比为决策提供直观数据支持。4. 常见问题与排查技巧实录在实际操作中总会遇到一些令人困惑的输出或现象。这里记录一些常见问题和排查技巧。4.1 为什么iostat显示的%util会超过100%这在多块磁盘的RAID阵列如RAID 0, RAID 10上很常见。因为%util是设备繁忙时间的百分比。对于RAID控制器管理的虚拟设备如/dev/md0一个逻辑IO可能会并行下发到多块物理磁盘。当这些物理磁盘同时工作时逻辑设备在统计周期内的“繁忙时间”可能会超过100%。例如一个双盘RAID 0如果两块盘都100%繁忙md0的%util就会显示200%。所以对于RAID设备%util失去了其绝对值意义更应该关注r_await/w_await和吞吐量指标。4.2iotop显示的总IO速率和iostat对不上这通常是正常的原因有几个缓存Cacheiostat报告的是块设备层的物理IO。而iotop默认报告的是进程发起的、经过VFS虚拟文件系统层的IO。如果进程读取的数据在页面缓存Page Cache中命中就不会产生物理磁盘读iostat看不到但iotop的进程DISK READ可能会计数取决于内核版本和设置。可以使用iotop -P或-a参数查看累积的物理IO或者使用pidstat -d它报告的更接近物理IO。合并Mergeiostat的rkB/s是合并后写入物理设备的数据量。而进程层发起的多个小IO可能在块层被合并成一个大的物理IO。设备映射如果使用了LVM、设备映射器dm或加密层iotop可能看到的是上层逻辑设备的IO而iostat看到的是底层物理设备或映射设备的IO。4.3 如何监控容器Docker/K8s内的磁盘IO容器内的进程看到的往往是宿主机的一部分设备或虚拟设备。直接在主机的iotop里可能无法准确区分容器的IO。有以下几种方法cgroup统计信息容器的IO限制和统计通过cgroup实现。可以查看对应容器的cgroup目录。# 找到容器的cgroup ID如从docker inspect获取 # 查看该容器的IO统计假设使用cgroup v1 cat /sys/fs/cgroup/blkio/docker/container-id/blkio.throttle.io_service_bytes cat /sys/fs/cgroup/blkio/docker/container-id/blkio.throttle.io_serviced这些文件记录了该cgroup内进程读写的字节数和IO次数。使用容器化工具在宿主机上使用docker stats命令可以查看容器的实时CPU、内存、网络和块IO使用情况。在Kubernetes中可以使用kubectl top pod结合Metrics Server或者通过cAdvisor、Prometheus等监控方案来收集容器级别的IO指标。进入容器内部docker exec进入容器在容器内部使用iostat、iotop等工具。但需要注意容器内可能没有安装这些工具且看到的是容器视角的设备可能是/dev/xvda1等虚拟设备其统计可能与宿主机视角不同。4.4 遇到“IO Wait”高但磁盘工具显示并不忙vmstat的wa高但iostat显示所有磁盘的%util和r_await/w_await都很低。这种情况可能的原因有NFS等网络文件系统IO等待发生在网络而不是本地磁盘。需要检查网络延迟和带宽以及NFS服务器的性能。可以使用sar -n DEV查看网络流量或使用nfsiostat如果可用专门查看NFS统计。内存压力导致Swap当物理内存不足时系统会频繁地将内存页换出Swap Out到交换分区Swap。这个换出操作是磁盘写但可能非常零散和随机导致高IO等待。检查vmstat的siswap in和soswap out列以及free命令查看swap使用情况。文件系统日志Journaling如ext4的journal日志写入。这部分写入有时是同步的可能导致短暂的等待。可以尝试调整文件系统挂载选项如datawriteback但需权衡数据安全风险。锁竞争有时高wa并非物理IO慢而是进程在等待某个文件锁或inode锁。这需要结合pidstat -w查看上下文切换和strace、perf等工具分析进程状态。4.5 排查工具箱速查表问题场景首要检查命令辅助/深入命令关键观察指标系统整体卡顿vmstat 1iostat -dx 2wa 5%,%util高,r_await/w_await高定位高IO进程sudo iotoppidstat -d 1DISK READ/WRITE,IO,kB_rd/s,kB_wr/s历史性能分析sar -dsar -u,sar -b历史时间段的tps,rkB/s,wkB/s,%util评估磁盘性能fio(定制测试)hdparm -Tt /dev/sda(缓存/缓冲读测试)IOPS, Bandwidth, Latency (clat percentiles)容器IO问题docker stats查看cgroup文件 (/sys/fs/cgroup/...)容器级别的读写字节数/次数深度延迟分析iostat -dx(看await)blktraceblkparsebttIO请求在各阶段Q2C, D2C等的耗时分布怀疑Swap导致IOfree -h,vmstat 1sar -W 1(查看swap统计)si,so持续不为0, swap使用率增长掌握这些工具和思路你就能像一位经验丰富的系统侦探一样从容应对各种磁盘IO相关的性能谜题。记住监控的目的不是为了看一堆数字而是为了建立系统的性能基线在异常出现时能快速定位、分析和解决。