news 2026/6/23 13:57:02

Linux上IO性能问题的故障排除实践

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Linux上IO性能问题的故障排除实践

文章目录

    • 引言
    • 详解Linux系统IO性能问题排查通用步骤
      • 1. 检查服务器负载
      • 2. 查看IO使用率
      • 3. 明确定位IO进程
      • 其他有用的IO分析工具
    • 小结
    • 参考

引言

在监控工具盛行的今天,学会传统的系统性能瓶颈排查手段也是必要的技术储备,它可以让你保持对系统指标的敏感度,而以下便是笔者整理的一套比较普适的IO性能瓶颈通用排查方法论,同时为了更好地复现这个问题,笔者也用Java写了一个多线程执行数据读写的程序,读者可以查看如下代码结合注释了解一下这个逻辑:

/** * 启动磁盘I/O操作以模拟高I/O负载 * 通过创建多个I/O任务线程来模拟高磁盘I/O负载 */privatestaticvoidstartDiskIOOperations(){log.info("开始高I/O磁盘操作...");log.info("在另一个终端中运行 'iostat -x 1' 来监控磁盘利用率。");// 创建固定线程数的线程池executor=Executors.newFixedThreadPool(NUM_THREADS);// 提交多个任务以连续写入磁盘for(inti=0;i<NUM_THREADS;i++){executor.submit(newIOTask(i));}log.info("磁盘I/O操作已启动,使用 {} 个线程",NUM_THREADS);}/** * 执行连续写入操作以模拟高I/O的任务 * 该类负责执行磁盘I/O操作,通过不断写入和清空文件来模拟高I/O负载 */staticclassIOTaskimplementsRunnable{privatefinalinttaskId;publicIOTask(inttaskId){this.taskId=taskId;}@Overridepublicvoidrun(){// 每个线程写入自己的临时文件Stringfilename="/tmp/disk_io_test_"+taskId+".tmp";try(FileOutputStreamfos=newFileOutputStream(filename)){log.info("线程-{} 正在写入 {}",taskId,filename);// 连续将数据写入文件并在每次写入后清空文件while(!Thread.currentThread().isInterrupted()){performDiskIOOperation(fos,taskId);ThreadUtil.sleep(500);}}catch(IOExceptione){log.error("线程-{} 发生错误: {}",taskId,e.getMessage());}}}/** * 执行磁盘I/O操作:写入指定大小的数据然后清空文件 * 该方法会连续写入数据到文件,然后清空文件内容,用于模拟高I/O负载 * @param fos 文件输出流 * @param taskId 任务ID * @throws IOException IO异常 */privatestaticvoidperformDiskIOOperation(FileOutputStreamfos,inttaskId)throwsIOException{longstartTime=System.currentTimeMillis();// 写入数据(分块写入)longbytesWritten=0;while(bytesWritten<WRITE_SIZE){fos.write(DATA);bytesWritten+=DATA.length;}fos.flush();// 强制写入磁盘// 清空文件内容fos.getChannel().truncate(0);longendTime=System.currentTimeMillis();// 打印本次操作的耗时log.info("线程-{} 完成一次写入和清空操作,耗时: {} ms",taskId,(endTime-startTime));}

我是SharkChili,Java 开发者,Java Guide开源项目维护者。欢迎关注我的公众号:写代码的SharkChili,也欢迎您了解我的开源项目 mini-redis:https://github.com/shark-ctrl/mini-redis。

为方便与读者交流,现已创建读者群。关注下方公众号获取我的联系方式,添加时备注加群即可加入。

我是SharkChiliJava开发者,Java Guide 开源项目维护者。欢迎关注我的公众号:写代码的SharkChili,也欢迎您了解我的开源项目 mini-redis:https://github.com/shark-ctrl/mini-redis。

为方便与读者交流,现已创建读者群。关注上方公众号获取我的联系方式,添加时备注加群即可加入。

详解Linux系统IO性能问题排查通用步骤

1. 检查服务器负载

当我们认为存在IO瓶颈时,首先要做的就是基于top指令查看当前服务器wa即CPU等待IO任务完成的占比,一般情况下20%以下算是一个比较合理的正常阈值,超过30%-40%则表明系统可能存在严重的IO瓶颈。以笔者的服务器为例,可以看到wa的值远大于正常范围,说明当前CPU基本处于等待IO任务完成的情况:

Tasks:34total,1running,33sleeping,0stopped,0zombie %Cpu0:0.5us,2.6sy,0.0ni,5.3id,90.5wa,0.0hi,1.1si,0.0st %Cpu1:0.0us,2.2sy,0.0ni,24.9id,72.4wa,0.0hi,0.5si,0.0st %Cpu2:1.1us,0.6sy,0.0ni,0.6id,97.7wa,0.0hi,0.0si,0.0st %Cpu3:0.5us,2.7sy,0.0ni,16.8id,80.0wa,0.0hi,0.0si,0.0st %Cpu4:0.6us,1.7sy,0.0ni,0.0id,97.8wa,0.0hi,0.0si,0.0st %Cpu5:0.0us,3.9sy,0.0ni,18.8id,77.3wa,0.0hi,0.0si,0.0st

2. 查看IO使用率

明确系统存在IO性能瓶颈的情况下,我们就需要更进一步定位问题,以笔者为例,一般会执行iostat指令,如下所示,大意为:

  1. -x:显示更多扩展信息(包括设备利用率、等待时间等)
  2. 每1秒输出1次,持续输出
iostat -x1

从输出结果来看,对应sdd盘使用率%util(IO利用率)飙到100%且iowait达到了78.2%,很明显这块磁盘存在一些异常IO读写任务:

avg-cpu: %user %nice %system %iowait %steal %idle0.0%0.0%1.0%78.2%0.0%20.8% Device r/s rMB/s rrqm/s %rrqm r_await rareq-sz w/s wMB/s wrqm/s %wrqm w_await wareq-sz d/s dMB/s drqm/s %drqm d_await dareq-sz f_await aqu-sz %util sda0.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.00sdb0.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.00sdc0.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.00sdd4.000.040.000.00122.2510.24171.00190.811.000.583884.171.120.000.000.000.000.000.000.00664.68100.00

关键指标解读:

  • %util:设备利用率,接近100%表示设备繁忙,可能存在IO瓶颈
  • r_awaitw_await:平均读写请求等待时间,数值越高说明IO响应越慢
  • aqu-sz:平均请求队列大小,数值较大说明IO请求堆积严重
  • await:平均服务时间(读写等待时间之和)

3. 明确定位IO进程

基于上述过程我们已经明确sdd盘存在IO异常,此时我们就可以通过iotop来查看具体进程了,需要补充的是iotop默认是没有安装的,读者可以参考网上教程自行安装,以笔者的Ubuntu系统为例,对应的安装指令为:

sudoaptinstalliotop

最后键入sudo iotop -o查看正在执行IO操作的进程,对应输出结果如下,对应字段含义分别是:

  1. Total DISK READ: 总磁盘读
  2. Total DISK WRITE: 总磁盘写
  3. Current DISK READ: 瞬时磁盘读
  4. Current DISK WRITE: 瞬时磁盘写
  5. TID:线程号
  6. PRIO:io进程优先级
  7. USER:进程所属用户
  8. DISK READ:该线程读取速率
  9. DISK WRITE:该线程写入速率
  10. COMMAND:执行线程的命令(对应java进程启动指令)

此时就可以非常明确地看到笔者Java进程对应执行异常IO操作的线程和读写速率了,可以看到笔者的大量进程都存在写入操作,占用大量磁盘写入带宽:

Total DISK READ:0.00B/s|Total DISK WRITE:142.99M/s Current DISK READ:11.92K/s|Current DISK WRITE:336.21M/s TID PRIOUSERDISK READ DISK WRITE>COMMAND3253712be/4 sharkchi0.00B/s18.26M/s java -jar web-cache-1.0.jar --app.startup.method=1[pool-2-thread-3]3253713be/4 sharkchi0.00B/s18.26M/s java -jar web-cache-1.0.jar --app.startup.method=1[pool-2-thread-4]3253711be/4 sharkchi0.00B/s18.25M/s java -jar web-cache-1.0.jar --app.startup.method=1[pool-2-thread-2]3253715be/4 sharkchi0.00B/s18.25M/s java -jar web-cache-1.0.jar --app.startup.method=1[pool-2-thread-6]3253714be/4 sharkchi0.00B/s18.24M/s java -jar web-cache-1.0.jar --app.startup.method=1[pool-2-thread-5]3253710be/4 sharkchi0.00B/s17.50M/s java -jar web-cache-1.0.jar --app.startup.method=1[pool-2-thread-1]3253717be/4 sharkchi0.00B/s17.50M/s java -jar web-cache-1.0.jar --app.startup.method=1[pool-2-thread-8]3253716be/4 sharkchi0.00B/s16.74M/s java -jar web-cache-1.0.jar --app.startup.method=1[pool-2-thread-7]

其他有用的IO分析工具

在实际排查中,除了上述工具外,还有其他一些有用的工具可以辅助分析:

  1. pidstat -d 1:显示每个进程的IO统计信息
  2. iotop -a:按IO累计使用量排序
  3. vmstat 1:显示虚拟内存统计,包括IO相关指标
  4. lsof +D /path/to/directory:列出打开指定目录下文件的进程

小结

我们来简单小结一下IO性能瓶颈的排查套路:

  1. 通过top命令查看%wa(iowait)指标,判断CPU是否存在异常等待IO的情况
  2. 使用iostat -x 1查看IO使用率和响应时间等详细指标,定位具体磁盘设备
  3. 使用iotop显示正在执行IO任务的进程和线程,明确问题程序
  4. 结合其他工具如pidstatvmstat等进行深入分析

当然,对于老司机而言,可能大部分都会在top指令完成后,明确存在io性能瓶颈且当前服务器是java进程专用后,就会直接通过iotop定位问题了,而这就是所谓的经验。

我是SharkChili,Java 开发者,Java Guide开源项目维护者。欢迎关注我的公众号:写代码的SharkChili,也欢迎您了解我的开源项目 mini-redis:https://github.com/shark-ctrl/mini-redis。

为方便与读者交流,现已创建读者群。关注下方公众号获取我的联系方式,添加时备注加群即可加入。

我是 SharkChili ,Java 开发者,Java Guide 开源项目维护者。欢迎关注我的公众号:写代码的SharkChili,也欢迎您了解我的开源项目 mini-redis:https://github.com/shark-ctrl/mini-redis。

为方便与读者交流,现已创建读者群。关注上方公众号获取我的联系方式,添加时备注加群即可加入。

参考

【双语视界】Linux上IO性能问题的故障排除:https://www.bilibili.com/video/BV14d35zhEjs/?from_spmid=united.player-video-detail.drama-float.0&plat_id=411&share_from=season&share_medium=iphone&share_plat=ios&share_session_id=2A52FF3A-393E-4D48-98A0-712F961E6C3A&share_source=WEIXIN&share_tag=s_i&spmid=united.player-video-detail.0.0&timestamp=1758040810&unique_k=gAzBCJY&vd_source=bf04f9a485aa892c0242fbfdfca25589

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/23 5:28:37

Go之路 - 7.go的函数

一、函数基础 1.1 函数声明 // 基本语法 func 函数名(参数列表) (返回值列表) {// 函数体 }// 示例 func add(x int, y int) int {return x y }// 简化参数类型&#xff08;相同类型&#xff09; func multiply(x, y int) int {return x * y }1.2 多返回值 // 返回多个值 func…

作者头像 李华
网站建设 2026/6/22 15:25:59

Chet.QuartzNet.UI 基于VbenAdmin框架的现代化UI体验

&#x1f525; Chet.QuartzNet.UI 基于VbenAdmin框架的现代化UI体验 &#x1f3af; 为什么VbenAdmin是个好选择&#xff1f; Chet.QuartzNet.UI 采用了 VbenAdmin 作为前端框架&#xff0c;VbenAdmin 是一款基于 Vue 3 TypeScript Ant Design Vue 开发的现代化管理系统框架&a…

作者头像 李华
网站建设 2026/6/23 3:01:20

AI 在泛前端领域的思考和实践-上篇

在大模型、AI Agent、Vibe Coding 与 Spec Coding 飞速发展的浪潮中&#xff0c;AI 与泛前端的融合正引发行业的深度思考&#xff1a;AI 究竟会 “替代” 传统开发模式&#xff0c;还是会推动一场效率与体验的全新 “革命”&#xff1f;它又将为泛前端领域带来哪些底层变革&…

作者头像 李华
网站建设 2026/6/23 19:52:33

靠谱的厦门考研哪个好选哪个

靠谱的厦门考研机构如何选择&#xff1a;以厦门博学乐思为例引言随着考研竞争的日益激烈&#xff0c;越来越多的学生开始寻求专业的考研辅导机构来提升自己的竞争力。在厦门&#xff0c;有许多考研辅导机构可供选择&#xff0c;但如何找到一个靠谱且适合自己的机构呢&#xff1…

作者头像 李华
网站建设 2026/6/23 11:09:48

高通万卫星:混合AI与分布式协同是未来 | MEET2026

编辑部 整理自 MEET2026量子位 | 公众号 QbitAI从“感知”到“生成”&#xff0c;再到自主行动的“智能体”&#xff0c;AI正在终端侧掀起一场无声的算力革命。在量子位MEET2026智能未来大会上&#xff0c;高通公司AI产品技术中国区负责人万卫星指出&#xff1a;尽管目前行业关…

作者头像 李华
网站建设 2026/6/22 20:56:33

AI图像编辑大师:InstructPix2Pix模型完全使用手册

AI图像编辑大师&#xff1a;InstructPix2Pix模型完全使用手册 【免费下载链接】instruct-pix2pix 项目地址: https://ai.gitcode.com/hf_mirrors/ai-gitcode/instruct-pix2pix InstructPix2Pix是一款革命性的AI图像编辑工具&#xff0c;它通过简单的文本指令就能实现复…

作者头像 李华