通过blktrace, debugfs分析磁盘IO

前几天微博上有同学问我磁盘util达到了100%时程序性能下降的问题,由于信息实在有限,我也没有办法帮太大的忙,这篇blog只是想给他列一下在磁盘util很高的时候如何通过blktrace+debugfs找到发生IO的文件,然后再结合自己的应用程序,分析出这些IO到底是谁产生的,最终目的当然是尽量减少不必要的IO干扰,提高程序的性能。

blktrace是Jens Axobe写的一个跟踪IO请求的工具,linux系统发起的IO请求都可以通过blktrace捕获并分析,关于这个工具的介绍请自行Google之,这里推荐我们部门的褚霸同学的blog,里面有好几篇文章分别介绍了blktrace, blkparse以及blkiomon等工具的使用。

debugfs是ext2, ext3, ext4文件系统提供的文件系统访问工具,通过它我们可以不通过mount文件系统而直接访问文件系统的内容,它是e2fsprogs的一部分,默认应该都是安装的,详细的说明可以通过man debugfs得到。

下面我来演示一下如何通过这两个工具的配合来找到磁盘IO的源头。

先看一个简单的例子:
在一个终端会输入如下命令:
while [ 1 ];do dd if=/dev/zero of=test_file bs=4k count=20 seek=$RANDOM oflag=sync;done
随机的在test_file里面写数据造成较大的IO压力,现在看看如何通过blktrace和debugfs抓到它。

1. 通过iostat观察到有很大的磁盘压力
Device: rrqm/s wrqm/s r/s w/s rsec/s wsec/s avgrq-sz avgqu-sz await svctm %util
sdb 0.00 2759.00 0.00 3515.50 0.00 50196.00 14.28 0.90 0.26 0.24 85.70

2. 我们看到sdb压力很大,这时候就需要通过blktrace抓取对应盘的数据
blktrace /dev/sdb 有IO压力的时候一会儿就可以了,通过ctrl+c停止抓取。
blktrace是需要debugfs支持的,如果系统提示debugfs没有mount,需要先mount上
mount -t debugfs none /sys/kernel/debug 再执行blktrace命令

3. 将blktrace抓出来的二进制文件转成文本格式。
blkparse sdb.blktrace.* > 1.log

4. 开始分析日志
grep ‘ A ‘ 1.log|head -n 5

8,16 0 39 0.001242727 2872 A WS 420143 + 8 <- (8,17) 420080
8,16 0 52 0.001361766 2872 A WS 420151 + 8 <- (8,17) 420088
8,16 0 65 0.001440210 2872 A WS 420159 + 8 <- (8,17) 420096
8,16 0 78 0.001518207 2872 A WS 420167 + 8 <- (8,17) 420104
8,16 0 91 0.001596083 2872 A WS 420175 + 8 <- (8,17) 420112

为啥要grep ‘ A ‘呢?因为这条信息是上层一个读写请求进入到Linux IO协议栈的第一步,只有在这里我们可以看到清晰的请求原始信息。比如
8,16 0 39 0.001242727 2872 A WS 420143 + 8 <- (8,17) 420080
这条说明是设备(8,17)也就是sdb1上产生的扇区为420080的写请求(读请求的话会在WS对应的位置出现‘R’),长度是8,它被映射到(8,16)上位置为420143。这个IO请求的完整生命周期是这样的:
8,16 0 39 0.001242727 2872 A WS 420143 + 8 <- (8,17) 420080
8,16 0 41 0.001244984 2872 G WS 420143 + 8 [dd]
8,16 0 43 0.001246609 2872 I WS 420143 + 8 [dd]
8,16 0 45 0.001255064 2872 D WS 420143 + 8 [dd]
8,16 0 46 0.001325168 0 C WS 420143 + 8 [0]
可以看到从’ A ‘的下一条开始都是以整个设备的扇区号为标识的,不方便我们找到对应的分区。

5. 下面就开始通过debugfs来分析这条读写请求的来源了。
(8, 17)是sdb1, 420080是扇区号(IO层的基本单位是扇区sector,大小是512bytes),而文件系统层是通过块block来管理的,一般的ext3,ext4的块block大小是4096[1],由此可得这个请求对应到文件系统的块block号是420080/8=52510, debugfs提供了命令icheck可以通过block号找到它对应的文件的inode。
#debugfs -R ‘icheck 52510′ /dev/sdb1
debugfs 1.43-WIP (1-Aug-2012)
BlockInode number
52510         12

6. 通过inode number找到对应的文件名,很幸运,debugfs又提供了另外一条命令ncheck可以找到inode对应的文件名[2]。
#debugfs -R ‘ncheck 12′ /dev/sdb1
debugfs 1.43-WIP (1-Aug-2012)
InodePathname
12//test_file
大家可以看到,我们现在已经成功找到了test_file这个文件啦,至此块设备层和文件系统层的分析工作已经结束了,下面就可以结合应用看看为啥会对这个文件有如此频繁的读写操作了!

[1] 块大小实际上也能够通过debugfs来得到。
debugfs -R ‘stats’ /dev/sdb1|grep “Block size”
[2] 有的同学找到的inode number是8,然后却无法找到对应的文件名。这是因为8是ext3/4文件系统中的日志文件的inode,它是隐藏文件,所以无法找到,可以再试试其他的block号哦!

转载于:https://www.cnblogs.com/zengkefu/p/5639200.html

<think>好的,用户现在问的是磁盘IO瓶颈,之前他们问过nmon文件中如何分析磁盘瓶颈,现在这个问题更泛一些,可能是想了解更一般的情况。我需要先回顾之前的回答,确保不重复,同时扩展信息。 首先,用户可能是系统管理员或者运维人员,他们在处理服务器性能问题,特别是磁盘相关的。需要给出具体的指标、分析方法解决方案。 之前的回答已经覆盖了nmon中的指标,比如DISKBUSY、吞吐量、AvgWait等。现在需要更通用的磁盘IO瓶颈分析,可能不局限于nmon工具。需要包括常见指标如IOPS、吞吐量、延迟,以及工具方面的扩展,比如iostat、sar等。 还要考虑用户可能遇到的场景,比如数据库慢、应用响应时间长,这时候如何确认是否是磁盘IO的问题。需要分步骤讲解如何识别分析,可能包括监控工具的使用,指标阈值,以及不同瓶颈类型的解决方案。 另外,用户可能需要实际案例来理解,比如高IOPS导致延迟上升,或者顺序读写与随机读写的区别。需要举例子说明。 还要注意避免太技术化的术语,用中文清晰解释概念,比如IOPS是什么,吞吐量的单位,延迟的意义。同时,确保LaTeX公式正确,按照之前的系统级指令使用$$$符号。 可能需要补充的工具部分,比如iostat的输出解读,pidstat找进程,fio测试工具。这些都是实际排查中常用的,用户可能想知道具体怎么做。 最后,解决方案部分要具体,比如升级硬件、优化应用、调整内核参数等,给出实际可行的建议。同时提醒用户结合硬件规格分析,比如不同类型的磁盘性能差异。 检查是否有遗漏点,比如并发请求的影响,队列长度,以及RAID配置的影响。确保覆盖全面,但不过于冗长。结构要清晰,分步骤子点,方便用户逐步排查。</think>在分析磁盘I/O瓶颈时,需要从**吞吐量、IOPS、延迟、队列深度**四个核心维度综合判断。以下是系统级分析框架: --- ### 一、关键性能指标 $$ \begin{cases} \text{IOPS(每秒I/O操作数)} & \text{随机读写能力} \\ \text{吞吐量(MB/s)} & \text{顺序读写带宽} \\ \text{延迟(Latency)} & \text{单次I/O响应时间} \\ \text{队列深度(Queue Depth)} & \text{并发I/O请求数} \\ \end{cases} $$ --- ### 二、瓶颈识别步骤 #### 1. 监控工具选择 - **Linux**:`iostat -x 1`(关注`%util`, `await`, `svctm`) - **Windows**:PerfMon(计数器:`Avg. Disk sec/Read`, `Disk Transfers/sec`) - **通用工具**:`sar`, `dstat`, `iotop` #### 2. 阈值判断 | 指标 | 机械硬盘(HDD) | SSD | |--------------|----------------------|---------------------| | **IOPS** | < 200 | 5万~100万+ | | **延迟** | > 20ms(异常) | > 5ms(异常) | | **%util** | > 70%(瓶颈风险) | > 90%(需警惕) | #### 3. 瓶颈类型诊断 - **IOPS瓶颈**: - 现象:`iostat`中`r/s + w/s`接近磁盘标称IOPS - 场景:数据库大量小事务、日志高频写入 - **吞吐量瓶颈**: - 现象:`MB_read/s + MB_wrtn/s`接近磁盘带宽上限 - 场景:大数据顺序读写、视频流处理 - **延迟瓶颈**: - 现象:`await` > 磁盘标称延迟2倍(如HDD > 40ms) - 根源:队列堆积或硬件性能不足 --- ### 三、深度分析工具链 1. **定位高负载进程**: ```bash pidstat -d 1 # 按进程统计I/O iotop # 实时I/O进程排名 ``` 2. **分析I/O模式**: ```bash blktrace /dev/sda # 跟踪设备请求 ``` 3. **压测验证**: ```bash fio --name=test --ioengine=libaio --rw=randread --bs=4k --numjobs=16 --size=1G --runtime=60 ``` --- ### 四、典型瓶颈场景与解决方案 #### 场景1:随机读密集型(如数据库) - **现象**:`%util`高但吞吐量低,`await`飙升 - **优化**: - 升级SSD并启用NVMe协议 - 调整MySQL的`innodb_buffer_pool_size` - 使用`deadline`或`none`调度器(SSD场景) #### 场景2:顺序写洪峰(如日志写入) - **现象**:周期性`MB_wrtn/s`触达磁盘带宽上限 - **优化**: - 启用写合并(write coalescing) - 分离日志盘与数据盘 - 使用LVM条带化提升并行度 #### 场景3:虚拟化环境I/O争抢 - **现象**:多VM同时高负载时`svctm`(服务时间)异常 - **优化**: - 启用Hypervisor的I/O控制组(cgroups) - 为关键VM分配virtio-blk的独立队列 - 配置QoS限制(如Ceph RBD的IOPS上限) --- ### 五、高级排查技巧 1. **内核参数调优**: ```bash echo 256 > /sys/block/sda/queue/nr_requests # 调整队列深度 echo deadline > /sys/block/sda/queue/scheduler ``` 2. **RAID配置影响**: - RAID5写惩罚:$ \text{实际IOPS} = \frac{\text{理论IOPS}}{4} $ - RAID10可提供最佳随机读写性能 3. **文件系统选择**: - 小文件密集型:XFS > ext4 - 海量文件:ZFS/Btrfs(需权衡内存开销) --- ### 六、验证瓶颈消除 通过**阿姆达尔定律**估算优化效果: $$ S = \frac{1}{(1-\alpha) + \frac{\alpha}{k}} $$ 其中: - $ \alpha $ = 受I/O限制的任务比例 - $ k $ = 磁盘性能提升倍数 当$ \alpha > 30\% $时,优化磁盘可获得显著收益。 > **注**:真实场景需结合`vmstat`的`bi`(入)、`bo`(出)CPU的`wa`(I/O等待)综合判断。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值