ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Linux磁盘IO排查实战:8个工具定位系统卡顿元凶

Linux磁盘IO排查实战:8个工具定位系统卡顿元凶 做运维这些年我最怕的不是CPU跑满也不是内存告警而是那种服务器明明看着没病、业务却像踩了棉花一样“软卡”的场面。CPU不高内存够用网络也没有波动可应用就是慢SSH登录都半天没反应。碰到这种状态十有八九是硬盘在拖后腿——而Linux下的硬盘性能诊断工具多到数不清真正能在生产环境里一锤定音的翻来覆去就是那几把。下面这套组合拳是我本人一线排查IO性能问题用得最顺手的8个利器覆盖了从“快速确认是不是硬盘的锅”到“揪出具体进程”再到“量化延迟、验证健康状态、深入IO链路”的完整过程。无论你是在传统物理机、云主机还是虚拟化环境里这套方法都能直接用。而且我可以负责任地说这8个工具都是各大Linux发行版自带或官方源里能装到的CentOS、Ubuntu、Rocky、openEuler这些发行版通用命令一个字都不差。1. 服务器卡顿的“隐形凶手”为什么先怀疑硬盘1.1 一次真实排障给我的教训先讲个我早年的亲身经历。某天线上应用突然响应变慢用户反馈“页面转圈转得厉害”我第一反应是看CPU和内存。top一看CPU使用率只有20%内存余量充足网络流量也正常。当时我一度怀疑是应用代码出了问题查了半天日志毫无头绪。后来我无意间按了1看每个核心发现CPU的wa指标飙到了40%以上。wa就是CPU花在等待IO完成上的时间占比这个数字一高基本就是告诉我是IO在拖后腿。再执行iostat -x -m 1果然一块数据盘的util直接冲到100%await也到了接近200毫秒。顺藤摸瓜用iotop一看一个日志进程正在疯狂写盘把整个存储链路全堵死了。那次之后我彻底学乖了遇到性能问题先把IO层排掉再往上查应用。顺序反了很容易绕大圈。1.2 弄清瓶颈在哪一层从IO请求的完整旅程说起如果不理解硬盘读写到底经历了哪些环节用工具时就会很迷茫不知道每个命令看的是哪一层的状态。你可以把一次硬盘读取想象成去餐厅点餐应用进程是顾客下单后坐在位子上等。文件系统和页缓存是前台负责接单、记账、有些菜如果有现成的被缓存的直接就端上来了。块设备层是后厨调度台负责把订单排队按顺序派给厨师。硬盘本身是厨师真正干活的人负责把原料加工成成品。一次IO请求从应用到磁盘大致要经过应用 - 页缓存Page Cache - 文件系统 - 块设备层排队 - 设备驱动程序 - 磁盘硬件 - 完成后逐级返回。如果慢了可能是排队排太长了可能是厨师手艺差也可能是前台把单子记错了。问题可能藏在任意一层而不同工具观测的恰好就是不同层iostat、sar看的是块设备层的统计结果。iotop、pidstat看的是应用进程这一层。fio、ioping主动制造流量去测设备能力。blktrace直接记录每个IO请求从入队到下发的完整时间线。所以下面这8个工具不是我随便凑数的它们正好对应了排查时必须覆盖的四个视角统计、进程、压测、链路。一层层扎进去才能定位根因。2. 八把工具的“分工表”别拿杀牛刀切菜也别拿水果刀砍骨头2.1 工具定位总览先上一张完整的分工表帮大家建立起整体印象。具体参数和实战案例在后面的章节逐个展开工具类型观测层核心用途iostat统计块设备层看每块盘的IOPS、吞吐、队列长度、延迟、使用率sar统计/历史系统层/块设备层回放历史IO数据故障已过也能倒查pidstat进程统计任务层定位具体进程的读写速率和IO等待时间iotop进程实时监控任务层实时看哪个进程在大量读写磁盘类似进程版IO topsmartctl设备健康硬盘SMART检查盘体健康查看坏道、重映射、寿命等fio主动压测块设备层模拟读写负载测硬盘性能上限和基线ioping延迟压测块设备/文件层测真实IO延迟特别适合找“慢存储”blktrace btt链路追踪块设备层完整记录IO请求各阶段耗时精确定位堵点这8个工具不是同一个重量级的。比如blktrace平时根本不用但关键时刻只有它能回答“到底堵在哪一毫秒”。而iostat基本是每次排查的起手式。2.2 我为什么按“统计-进程-链路”三层来用这8个工具这套工具的使用逻辑我总结成一句话先定性再定位最后深挖。第一步用iostat和sar做统计回答“是不是IO出问题了”以及“哪块盘出问题了”。这一步只花10秒钟但能避免在错误的方向上浪费时间。第二步用iotop和pidstat定位进程回答“是哪个程序在搞事”。很多时候查到这一步就有结论了比如发现日志进程、备份任务、慢SQL在擦盘。第三步如果还查不出来再用fio、ioping验证设备能力判断是硬盘真不行还是业务量太大。极少情况下以上全都正常但业务依然慢这时候就该上blktrace btt看链路内部到底哪一段耗时异常。工具的使用场景一定要分清楚我见过不少同事在fio压测上花一下午最后发现只是日志写太频——方向错了工具再好也是白搭。3. 第一组iostat / sar / pidstat 把“是不是硬盘的锅”先钉死3.1 iostat 输出里的几个数字到底怎么读iostat是sysstat包里的工具也是我每次排查性能问题的起手式。我最常执行的命令是iostat -x -m 1 5参数含义-x显示扩展统计信息-m以MB/s为单位显示吞吐1 5表示每秒采样一次、共采样5次。第一次输出是系统启动以来的平均值参考价值不大重点看后面几次的实时值。输出长这样Device r/s w/s rMB/s wMB/s rrqm/s wrqm/s %rrqm %wrqm r_await w_await aqu-sz rareq-sz wareq-sz %util sda 12.30 245.80 0.63 18.42 0.00 34.22 0.00 12.22 8.31 190.22 45.83 52.4 76.8 100.00看起来一团数字但你需要关注的没几个r/s 和 w/s每秒读请求数和写请求数反映IOPS。要注意磁盘和SSD在这个指标上的量级差异很大机械盘通常几百就算高SSD几万也不稀奇。rMB/s 和 wMB/s每秒读写吞吐量。r_await 和 w_await读/写请求的平均完成时间单位是毫秒。这个指标直接反映“请求发出去到完成回来”花了多久是判断延迟的核心依据。aqu-sz平均队列长度。这个数越大说明积压的请求越多排队越严重。%util设备忙时间百分比。这个指标很容易被误读后面我会专门写一节讲它是怎么骗人的。怎么判断异常给你一个经验参考机械盘await正常应在几十毫秒以内SSD应在一毫秒到几毫秒之间。如果达到三位数一百多毫秒说明磁盘已经处于亚健康或过载状态。但如果await很高而util并不高问题可能在调度器、驱动或者文件系统层不一定是盘本身的问题。3.2 sar 回放历史故障已过现场还在排查性能问题时最尴尬的场景是故障发生了但等你去查的时候业务已经恢复现场没了。这时候sar就是你的时间机器。sar同样来自sysstat包很多服务器自带定时采集历史数据默认保留在/var/log/sa/目录下。看当天的实时统计sar -d -p 1 3回放历史数据比如查看昨天下午2点到3点的IO情况sar -d -p -f /var/log/sa/sa$(date -d yesterday %d) -s 14:00:00 -e 15:00:00输出里每一行对应一个设备重点看tps每秒传输次数、rd_sec/s、wr_sec/s和avgrq-sz这几个字段基本能还原当时的吞吐和负载水平。我的建议是给所有服务器都装上sysstat并开启采集采集间隔用默认的10分钟就行也可以根据你业务的敏感度调到5分钟。磁盘空间占用极小关键时候能保命。没有历史数据就只能靠事后推断和盲人摸象没什么区别。3.3 pidstat -d把嫌疑进程揪出来当iostat确认某块盘确实是瓶颈后下一步就是找出是什么进程在制造压力。pidstat可以按进程维度展示IO信息pidstat -d 1 5关注三个字段kB_rd/s表示每秒读字节数kB_wr/s表示每秒写字节数iodelay表示进程在IO等待上消耗的墙钟时间毫秒。iodelay这个字段特别值钱——它直接告诉你这个进程有多少时间是在等IO等得越久越说明它的性能被存储拖累了。和iotop相比pidstat的优势是更节省资源、适合脚本化和后台采集而iotop的优势是交互式界面更直观。实际使用时我通常两个都看先用pidstat确认是哪个进程再用iotop观察它的动态行为。4. 第二组iotop / smartctl 从进程读写到硬盘健康做一次全面“体检”4.1 iotop 实战一次日志风暴是怎么被发现的iotop的输出长得很像top但它显示的不是CPU占用而是每个进程的磁盘IO情况。我最常用的命令是iotop -oP -d 2-o只显示有IO操作的进程-P显示进程而非线程默认显示线程线程太多时会刷屏-d 2每2秒刷新一次。这么一执行谁在读写、每秒读多少、每秒写多少、IO等待占比是多少全都清清楚楚。举一个我遇到过的典型场景某天iostat显示磁盘util很高但数据库负载很低排查了一圈没找到元凶。后来用iotop -oP一看一个Java日志框架的进程在疯狂刷日志磁盘写速率飙到每秒几百MB。原因是误把日志级别调成了DEBUG一条请求打几十行日志加上日志文件没有做轮转切割直接把盘写满了。把日志级别调回INFO再做轮转故障立刻消失。这里有个坑要提醒你iotop显示的读写速度是进程向系统发起的IO速率不是磁盘上实际落盘的速率。因为内核有页缓存进程的“写成功”可能只是写到了内存里真正的落盘写是异步发生的。所以如果你发现iotop显示的速率很高但iostat的写速度没那么高通常说明数据还在缓存里积压后面迟早要落盘——这种“虚假繁荣”最容易麻痹人。4.2 smartctl 看哪些属性才算“懂行”smarctl是smartmontools包提供的工具用来读取硬盘的SMART信息。SMART是硬盘自己记录的健康日志相当于汽车的仪表盘。两条命令最常用smartctl -H /dev/sda # 只看健康状态摘要 smartctl -a /dev/sda # 看完整SMART属性-H输出一个PASSED或FAILED简单但信息量太少。真正有用的是-a输出里的各属性表类似于ID# ATTRIBUTE_NAME FLAG VALUE WORST THRESH TYPE UPDATED WHEN_FAILED RAW_VALUE 5 Reallocated_Sector_Ct 0x0033 100 100 010 Pre-fail Always - 0 197 Current_Pending_Sector 0x0032 100 100 000 Old_age Always - 0 199 UltraDMA_CRC_Error_Count 0x003e 200 200 000 Old_age Always - 0不同品牌的盘属性编号会有些差异但我建议重点关注这几项Reallocated_Sector_Ct重映射扇区数硬盘发现物理坏道后会用备用扇区替换坏扇区这个值记录的就是替换了多少次。正常应为0一旦大于0且持续增长说明盘体正在加速恶化该准备迁移数据和换盘了。Current_Pending_Sector等待重映射的扇区数硬盘已经发现但还没处理的坏扇区。每次读写碰到这些扇区轻则延迟飙高重则直接报IO错误。这个值不为0就要高度警惕。UltraDMA_CRC_Error_CountCRC校验错误计数这个值高往往不是盘体问题而是SATA线缆或接口接触不良、信号质量差查查线缆比换盘更有效。对SSD还要额外关注ID 177 Wear_Leveling_Count磨损均衡次数和ID 233 Media_Wearout_Indicator寿命剩余百分比判断颗粒寿命还剩多少。必须强调一点SMART是慢变量指标盘体故障前不一定有明显异常。很多固态硬盘直接猝死SMART全绿。所以SMART只能作为参考不能作为唯一依据。真正判断盘是否健康要结合iostat的延迟表现综合判断。另外dmesg里如果出现I/O error、task abort之类的关键字那比SMART更紧急说明盘已经在实际报错了。5. 第三组fio / ioping 用主动压测定义“正常基线”5.1 fio 压测的常用姿势与参数解读iostat和iotop都是被动观测看的是现有业务对盘的压力。要判断一块盘“到底行不行”就需要主动制造压力做压测。fio是这领域的标准工具没有之一。四类最基础的测试命令建议收藏# 顺序读测大带宽 fio --nameseqread --filename/data/fio_test --rwread --bs1M --iodepth32 --numjobs4 --runtime30 --time_based --group_reporting --ioenginelibaio --direct1 # 顺序写测大带宽写入 fio --nameseqwrite --filename/data/fio_test --rwwrite --bs1M --iodepth32 --numjobs4 --runtime30 --time_based --group_reporting --ioenginelibaio --direct1 # 随机读测IOPS fio --namerandread --filename/data/fio_test --rwrandread --bs4k --iodepth32 --numjobs4 --runtime30 --time_based --group_reporting --ioenginelibaio --direct1 # 随机写测写IOPS和最坏延迟 fio --namerandwrite --filename/data/fio_test --rwrandwrite --bs4k --iodepth32 --numjobs4 --runtime30 --time_based --group_reporting --ioenginelibaio --direct1有一堆参数但关键的就这几个--direct1绕过页缓存直接写盘。不加这个参数写测试很可能全命中内存缓存测出来的数据是假的。--bs块大小。顺序测试用1MB随机测试用4KB这基本是业界习惯贴合实际应用的IO模型。--iodepth队列深度表示有多少个IO请求同时在途。对SSD队列深度不够时测不出真实性能。--numjobs并发进程数模拟多线程同时读写。--runtime和--time_based让测试跑固定时间而不是写完指定大小就停。--group_reporting把多个job的结果汇总输出否则要手动加好几个数。两个大坑必须提醒第一测试文件--filename一定不要放在根分区或系统盘上否则压测很可能把系统盘写满导致服务器故障。最好挂一块独立的测试盘或者用文件所在目录的绝对路径。第二写测试之前务必确认磁盘剩余容量比如bs1M配合size10G直接要写10GB。测试完记得删掉测试文件。5.2 不同盘的合理性能区间压测完需要知道数据是否正常。给一个大致量级供参考具体数值以盘型号为准但差太多基本可以断定盘有问题或接口/线缆不行磁盘类型顺序读顺序写4K随机读4K随机写机械盘HDD100-200MB/s80-150MB/s100-200 IOPS100-200 IOPSSATA企业级SSD400-550MB/s300-500MB/s5万-9万 IOPS3万-6万 IOPSNVMe SSD1.5-7GB/s1-5GB/s30万 IOPS10万 IOPS如果压测结果远低于这个区间优先检查SATA接口速率、线缆质量再看RAID卡缓存策略和固件设置。切记实测数据要看fio汇总里的IOPS、BW带宽、clat完成延迟三块。5.3 ioping 延迟测试能发现什么fio测的是吞吐量和整体性能但有时候业务的瓶颈不在吞吐而在单次IO的延迟。尤其是数据库这类对延迟极度敏感的应用哪怕一次fsync多等几毫秒都会直接反映在事务响应时间上。这时候就用得上iopingioping -c 20 -s 4k -W /数据盘目录-c 20测20次-s 4k每次测4KB大小-W表示每次写入都调用fsync强制落盘后才进行下一次测的是真实落盘延迟而不是缓存延迟。输出会给出每探测的延迟以及最小/平均/最大延迟。判断标准本地机械盘的随机4K落盘延迟通常在5-15毫秒本地SSD在100微秒到1毫秒之间。如果你测出来一个号称SSD的盘延迟到了几十毫秒那盘的状态多半已经出问题了。我曾经用这招验出一块只报SMART警告却没人信的SSD——ioping一测平均延迟80毫秒当场定罪。6. 第四组blktrace btt 搭一个“行车记录仪”看I/O到底堵在哪6.1 blktrace 与 blkparse 的基本用法前面几组工具能回答“是不是盘慢”“谁在产生IO”但如果遇到更诡异的场景——盘看起来没满负载进程也在正常读写可延迟就是高这时候就需要blktrace出马了。它能在内核块设备层捕获每个IO请求的完整生命周期相当于给每个IO装了一个行车记录仪。抓取10秒数据blktrace -d /dev/sda -o trace -w 10-d指定块设备-o指定输出文件名前缀-w 10抓10秒。抓完后当前目录会生成trace.blktrace.0这样的文件。blktrace抓到的原始数据是二进制格式需要先用blkparse解码成可读文本blkparse -i trace.blktrace.0 -o trace.txt解码后你会看到大量事件行每个事件都有类型标记。不需要每个都看懂但有几个关键事件要认识QQueueIO请求进入块层队列。MMerge请求与其他请求合并了。DDispatch请求被下发给磁盘驱动程序真正离开Linux IO调度器。CComplete磁盘完成请求处理并返回。一个IO从进入到完成会依次记录Q、D、C等事件。通过比较这些事件的时间戳就能算出请求在每一段各花了多久。这就是btt要做的事。6.2 btt 报告里的几个关键时间把解码后的数据交给btt汇总成统计报告btt -i trace.blktrace.0 -o btt.outbtt会输出每个设备的IO流程耗时统计重点关注这几个阶段Q2G请求入队到被分派给调度器的时间。这个值偏大说明IO调度层排队严重。G2I / I2D调度器内部处理到最终D的事件。一般占比很小。D2C请求下发给磁盘到完成的时间。这个值偏大说明磁盘硬件本身响应慢或者驱动/固件有问题。Q2C总耗时是Q2G、D2C等各阶段的和。这个工具的价值在于它能精确定位“慢在哪一段”。举个例子某次业务报告写入延迟高iostat看util只有30%fio压测也正常看起来都很诡异。用blktrace一抓btt报告显示D2C占了总耗时的90%以上说明瓶颈在磁盘硬件的实际完成时间再加上D2C延迟起伏很大最终锁定是磁盘固件在后台做垃圾回收导致瞬时响应恶化。这种结论不用blktrace基本不可能查出来。需要说明的是blktrace btt对系统有一定开销生产环境不要长时间抓取抓几十秒到几分钟够用在低峰期操作更稳妥。7. 从症状到结论一套可以直接抄作业的排查流程7.1 场景与初判工具说完了下面把这些工具串成一个完整的排查流程。假设场景某公司业务反馈“系统变慢了”你在服务器上看到load average偏高但CPU使用率没到瓶颈。第一步先执行三个基础命令top -bn1 | head -n 5 vmstat 1 5 uptime看什么重点看top里的wa字段、vmstat里的waCPU等待IO时间和b阻塞在IO上的进程数以及load average趋势。如果wa持续大于20%或者b列长期有数基本可以初步判定IO层有问题进入下一步。7.2 逐步执行与判断第二步iostat -x -m 1 3确认具体设备和方向。判断逻辑我给一个简单的分支某块盘util高接近100%同时await高盘被压满需要进一步定位谁在读写。某块盘util不高但await高盘本身响应慢或者调度/驱动层有问题优先看SMART和dmesg。所有盘util和await都不高瓶颈可能在文件系统锁、网络存储链路、RAID卡甚至不是IO问题回头查应用。第三步iotop -oP或pidstat -d 1 5定位进程。如果找到某进程确实在大量读写先搞清楚为什么它在读写在写日志备份数据库慢查询数据迁移很多情况下查到这一步真相已经大白。第四步怀疑盘体健康时执行smartctl -a /dev/sdX同时dmesg | grep -i error看看有没有内核报错。第五步用ioping -c 200 /路径测延迟基线。如果延迟明显高于该类型盘应有水平再用fio做一轮压测确认极限能力。第六步如果以上检查全都找不出问题执行blktrace -d /dev/sdX -w 30抓一段链路数据用btt定位具体是哪个环节的耗时异常。7.3 常见的五种结论排查走完结论大多逃不出这五类结论类型典型案例对应证据盘体老化/坏道HDD坏道、SSD颗粒老化SMART属性异常、dmesg报错、ioping延迟飙升进程IO风暴日志刷屏、备份任务重叠、慢SQLiotop/pidstat定位到具体进程存储链路故障线缆松动、RAID卡缓存策略错误CRC错误计数高、DD2C延迟异常、fio性能远低于标称文件系统/容量问题磁盘使用率超85%、inode耗尽df -h、df -i文件系统分配变慢业务量确实超过存储能力高峰期流量大但盘无故障压测值正常、延迟和util随业务量同步变化把这五类结论贴到排查记录里基本就能交代清楚一次性能问题的来龙去脉了。8. 我在一线踩过的坑哪些数据会骗人8.1 别被 %util 骗了iostat里最容易误导人的就是%util。很多人都以为util到了100%就代表盘满了其实不然。%util的原始含义是“设备在采样周期内有IO请求未完成的时间比例”注意它不统计并发度。对支持并行命令的NVMe SSD来说哪怕只有一个很小的请求挂在队列里util也可能显示100%但盘根本没吃饱。我见过太多新人看到util 100%就喊换盘结果换了盘util还是100%。正确姿势是把util和r_await/w_await、aqu-sz以及实际IOPS结合起来看如果util高但await正常、IOPS又低于预期值那可能是并发不够或者业务本身请求太少如果util高且await也高才说明真正在排队。8.2 机械盘和固态盘要用不同的判断标准机械盘的性能地图和SSD完全不同。机械盘最怕随机IO寻道时间是硬伤队列一深就崩所以await稍微升高就要警惕。而SSD的优势恰恰在于随机IO和并行能力但它的天敌是大规模连续写入、过热掉速和寿命衰减。比如NVMe SSD连续写入一段时间后会因为缓存耗尽和主控发热而掉速这时候如果只看吞吐你会误以为盘坏了其实等温度降下来、缓存排空后又能恢复。SSD还要关注TRIM是否开启否则长期使用后写性能会逐渐劣化。可以检查挂载参数里有没有discard或系统是否定期执行fstrim这也是性能问题排查中容易忽略的点。8.3 工具之外还容易漏掉的几件事除了上面工具的坑还有一些实战中很容易被忽视但影响很大的点。第一RAID卡策略。一台服务器用RAID卡接多块物理盘卡的缓存策略如果被改成write-through或电池/电容失效导致回写降级写入性能会断崖式下跌。遇到写性能差先看RAID卡状态再怀疑盘。第二文件系统使用率。ext4和xfs在使用率超过85%以后元数据分配会明显变慢业务上表现为“磁盘空间还剩不少但越来越卡”。用df -h看不出来得用df -i查inode耗尽情况。我处理过一次“明明还有50%空间但写不进去”的工单结果就是inode被小文件堆满了。第三挂载参数。noatime基本是标准配置如果没有加每次读文件都要更新访问时间会白白增加很多写IO。barrier和discard设置不当也会影响性能和寿命。最后说一个我个人养成的习惯新服务器上线前我一定会用fio和ioping把顺序读/写、随机读/写、4KB延迟的基线数据存档顺便用smartctl留一份SMART快照。等哪天业务说变慢了拿出基线一对比再结合iostat的趋势和历史sar数据半小时内就能判断是硬盘老化、业务压力变大还是系统配置出了问题。工具不在多关键是知道它该在排障的哪个环节出现以及它告诉你的数字到底意味着什么。这套方法论我不敢说能解决所有存储问题但至少能让你在八成的IO故障面前不吃亏。
返回列表