0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

如何快速分析定位 I/O 性能问题

科技绿洲 来源:Linux开发架构之路 作者:Linux开发架构之路 2023-11-13 14:15 次阅读

如何快速分析定位 I/O 性能问题

1. 文件系统 I/O性能指标

首先,想到是存储空间的使用情况,包括容量、使用量、以及剩余空间等。我们通常也称这些为磁盘空间的用量,但是这只是文件系统向外展示的空间使用,而非在磁盘空间的真实用量,因为文件系统的元数据也会占用磁盘空间。而且,如果你配置了RAID,从文件系统看到的使用量跟实际磁盘的占用空间,也会因为RAID级别不同而不一样。

除了数据本身的存储空间,还有一个容易忽略的是索引节点的使用情况,包括容量、使用量、剩余量。如果文件系统小文件数过多,可能会碰到索引节点容量已满的问题。

其次,缓存使用情况,包括页缓存、索引节点缓存、目录项缓存以及各个具体文件系统的缓存。通过使用内存,来临时缓存文件数据或者文件系统元数据,从而减少磁盘访问次数。·

最后,文件 I/O的性能指标,包括IOPS(r/s、w/s)、响应时间(延迟)、吞吐量(B/s)等。考察这类指标时,还要结合实际文件读写情况,文件大小、数量、I/O类型等,综合分析文件 I/O 的性能。

2. 磁盘 I/O性能指标

磁盘 I/O的性能指标,主要由四个核心指标:使用率、IOPS、响应时间、吞吐量,还有一个前面提到过,缓冲区。

考察这些指标时,一定要注意综合 I/O的具体场景来分析,比如读写类型(顺序读写还是随机读写)、读写比例、读写大小、存储类型(有无RAID、RAID级别、本地存储还是网络存储)等。

不过考察这些指标时,有一个大忌,就是把不同场景的 I/O指标拿过来作对比。

图片

3. 性能工具

一类:df、top、iostat、pidstat;

二类:/proc/meminfo、/proc/slabinfo、slabtop;

三类:strace、lsof、filetop、opensnoop

4. 性能指标及性能工具之间的关系

图片

5. 如何迅速分析 I/O性能瓶颈

简单来说,就是找关联。多种性能指标间,都是存在一定的关联性。想弄清楚指标之间的关联性,就要知晓各种指标的工作原理。出现性能问题,基本的分析思路是:

先用 iostat发现磁盘 I/O的性能瓶颈;

再借助 pidstat,定位导致性能瓶颈的进程;

随后分析进程 I/O的行为;

最后,结合应用程序的原理,分析这些 I/O的来源。

图片

图中列出最常用的几个文件系统和磁盘 I/O的性能分析工具,及相应的分析流程。

磁盘 I/O性能优化的几个思路

1. I/O基准测试

在优化之前,我们要清楚 I/O性能优化的目标是什么?也就是说,我们观察的这些 I/O指标(IOPS、吞吐量、响应时间等),要达到多少才合适?为了更客观合理地评估优化效果,首先应该对磁盘和文件系统进行基准测试,得到它们的极限性能。

fio(Flexible I/O Tester),它是常用的文件系统和磁盘 I/O的性能基准测试工具。它提供了大量的可定制化的选项,可以用来测试,裸盘或者文件系统在各种场景下的 I/O性能,包括不同块大小、不同 I/O引擎以及是否使用缓存等场景。

fio的选项非常多,这里介绍几个常用的:

# 随机读
fio -name=randread -direct=1 -iodepth=64 -rw=randread -ioengine=libaio -bs=4k -size=1G -numjobs=1 -runtime=1000 -group_reporting -filename=/dev/sdb
# 随机写
fio -name=randwrite -direct=1 -iodepth=64 -rw=randwrite -ioengine=libaio -bs=4k -size=1G -numjobs=1 -runtime=1000 -group_reporting -filename=/dev/sdb
# 顺序读
fio -name=read -direct=1 -iodepth=64 -rw=read -ioengine=libaio -bs=4k -size=1G -numjobs=1 -runtime=1000 -group_reporting -filename=/dev/sdb
# 顺序写
fio -name=write -direct=1 -iodepth=64 -rw=write -ioengine=libaio -bs=4k -size=1G -numjobs=1 -runtime=1000 -group_reporting -filename=/dev/sdb

重点解释几个参数

  • direct,是否跳过系统缓存,iodepth1 是跳过。
  • iodepth,使用异步 I/O(AIO)时,同时发出的请求上限。
  • rw,I/O模式,顺序读 / 写、随机读 / 写。
  • ioengine,I/O引擎,支持同步(sync)、异步(libaio)、内存映射(mmap)、网络等各种 I/O引擎。
  • bs,I/O大小。 4k,默认值。
  • filename,文件路径,可以是磁盘路径,也可以是文件路径。不过要注意,用磁盘路径测试写,会破坏这个磁盘的文件系统,所以测试前,要注意备份。

下面展示, fio测试顺序读的示例:

read: (g=0): rw=read, bs=(R) 4096B-4096B, (W) 4096B-4096B, (T) 4096B-4096B, ioengine=libaio, iodepth=64
fio-3.1
Starting 1 process
Jobs: 1 (f=1): [R(1)][100.0%][r=16.7MiB/s,w=0KiB/s][r=4280,w=0 IOPS][eta 00m:00s]
read: (groupid=0, jobs=1): err= 0: pid=17966: Sun Dec 30 08:31:48 2018
   read: IOPS=4257, BW=16.6MiB/s (17.4MB/s)(1024MiB/61568msec)
    slat (usec): min=2, max=2566, avg= 4.29, stdev=21.76
    clat (usec): min=228, max=407360, avg=15024.30, stdev=20524.39
     lat (usec): min=243, max=407363, avg=15029.12, stdev=20524.26
    clat percentiles (usec):
     |  1.00th=[   498],  5.00th=[  1020], 10.00th=[  1319], 20.00th=[  1713],
     | 30.00th=[  1991], 40.00th=[  2212], 50.00th=[  2540], 60.00th=[  2933],
     | 70.00th=[  5407], 80.00th=[ 44303], 90.00th=[ 45351], 95.00th=[ 45876],
     | 99.00th=[ 46924], 99.50th=[ 46924], 99.90th=[ 48497], 99.95th=[ 49021],
     | 99.99th=[404751]
   bw (  KiB/s): min= 8208, max=18832, per=99.85%, avg=17005.35, stdev=998.94, samples=123
   iops        : min= 2052, max= 4708, avg=4251.30, stdev=249.74, samples=123
  lat (usec)   : 250=0.01%, 500=1.03%, 750=1.69%, 1000=2.07%
  lat (msec)   : 2=25.64%, 4=37.58%, 10=2.08%, 20=0.02%, 50=29.86%
  lat (msec)   : 100=0.01%, 500=0.02%
  cpu          : usr=1.02%, sys=2.97%, ctx=33312, majf=0, minf=75
  IO depths    : 1=0.1%, 2=0.1%, 4=0.1%, 8=0.1%, 16=0.1%, 32=0.1%,  >=64=100.0%
     submit    : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%,  >=64=0.0%
     complete  : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.1%,  >=64=0.0%
     issued rwt: total=262144,0,0, short=0,0,0, dropped=0,0,0
     latency   : target=0, window=0, percentile=100.00%, depth=64

Run status group 0 (all jobs):
   READ: bw=16.6MiB/s (17.4MB/s), 16.6MiB/s-16.6MiB/s (17.4MB/s-17.4MB/s), io=1024MiB (1074MB), run=61568-61568msec

Disk stats (read/write):
  sdb: ios=261897/0, merge=0/0, ticks=3912108/0, in_queue=3474336, util=90.09%

这个示例中,重点关注几行,slat、clat、lat,以及 bw和 iops。前三者,都是指 I/O延迟,但是有不同之处:

slat,是指从 I/O提交到实际执行 I/O的时长;

clat,是指从 I/O提交到 I/O完成的时长;

lat,是指从 fio创建 I/O 到 I/O完成的时长。

这里需要注意的是,对同步 I/O来说,提交和完成是一个动作,slat就是 I/O完成的时间,clat是0;使用异步 I/O时,lat 约等于 slat + clat。

再来看bw,他表示吞吐量,上面的输出中,平均吞吐量是16MB(17005/1024)。

最后的IOPS,其实是每秒 I/O的次数,上面输出的平均 IOPS是 4250.

通常情况下,应用程序的IO 读写是并行的,每次的 I/O大小也不相同。所以上面的几个场景并不能精确模拟应用程序的 I/O模式。幸运的是,fio支持 I/O 的重放,需要先用 blktrace,记录磁盘设备的 I/O访问情况,再使用 fio,重放 blktrace的记录。

# 使用blktrace跟踪磁盘I/O,注意指定应用程序正在操作的磁盘
$ blktrace /dev/sdb
# 查看blktrace记录的结果
# ls
sdb.blktrace.0  sdb.blktrace.1
# 将结果转化为二进制文件
$ blkparse sdb -d sdb.bin
# 使用fio重放日志
$ fio --name=replay --filename=/dev/sdb --direct=1 --read_iolog=sdb.bin

2. I/O性能优化思路

应用程序优化

应用程序处于 I/O栈的最上端,可以通过系统调用,来调整 I/O模式(顺序还是随机、同步还是异步),同时也是数据的最终来源。下面总结了几个方面来优化应用程序性能:

第一,可以用追加写代替随机写,减少寻址开销,加快 I/O写的速度。

第二,借助缓存 I/O,充分利用系统缓存,降低实际 I/O的次数。

第三,在应用程序内部构建自己缓存,或者使用Redis这种的外部缓存系统。这样不仅可以在内部控制缓存的数据和生命周期,而且降低其他应用程序使用缓存对自身的影响。比如,C标准库,提供的fopen、fread等库函数,都会利用标准库缓存,减少磁盘的操作。而如果直接使用open、read等系统调用时,就只能利用操作系统的页缓存和缓冲区等。

第四,在需要频繁读写同一块磁盘空间时,可以使用 mmap 代替 read/write,减少内存的拷贝次数。

第五,在需要同步写的场景中,尽量将写请求合并,而不是让每个请求都同步写磁盘,即可用fsync() 代替 O_SYNC。

第六,在多个应用程序共享相同磁盘时,为了保证 I/O不被某个应用完全占用,推荐使用 cgroups 的 I/O子系统,来限制进程/进程组的 IOPS 以及吞吐量。

最后,在使用CFQ 调度器时,可以用 ionice来调整进程的 I/O调度优先级,特别是提高核心应用的 I/O优先级,他支持三个优先级类:Idle、Best-effort 和 Realtime。其中,后两者还支持 0-7的级别,数值越小,优先级越高。

文件系统优化

应用程序在访问普通文件时,是通过文件系统间接负责,文件在磁盘中的读写。所以跟文件系统相关的也有很多优化方式。

第一,可以根据实际负载场景的不同,选择合适的文件系统。比如,Ubuntu默认使用ext4,Centos默认使用 xfs。相比于ext4,xfs支持更大的磁盘分区和更大的文件数量。xfs支持大于 16TB的磁盘,但它的缺点在于无法收缩,而ext4可以。

第二,在选好文件系统后,可以优化文件系统得配置选项。包括文件系统的特性(如 ext_attr、dir_index)、日志模式(如 journal、ordered、writeback等)、挂载选项(如 noatime)等等。比如在使用 tune2fs这个工具,可以调整文件系统的特性,也常用来查看文件系统超级块的内容。而通过 /etc/fstab,或者mount,来调整文件系统的日志模式和挂载选项等。

第三,优化文件系统的缓存。比如,可以优化 pdflush的脏页刷新频率(设置dirty_expire_centisecs 和 dirty_writeback_centisecs)以及脏页限额(调整 dirty_background_ratio 和 dirty_ratio)。再如,还可以优化内核回收目录项缓存和索引节点缓存的倾向,及调整 vfs_cache_pressure(
/proc/sys/vm/vfs_cache_pressure,默认值100),数值越大,表示越容易回收。

最后,在不需要持久化时,可以用内存文件系统 tmpfs 以获得更好的 I/O性能。tmpfs直接把数据保存在内存中,而不是磁盘中。比如 /dev/shm,就是大多数Linux默认配置的一个内存文件系统,它的大小默认为系统总内存的一半。

磁盘优化

数据的持久化,最终要落到物理磁盘上,同时磁盘也是整个 I/O栈的最底层。从磁盘角度出发,也有很多优化方法:

第一,最简单的就是SSD代替 HDD。

第二,使用 RAID把多块磁盘组合成一个逻辑磁盘,构成冗余独立的磁盘阵列,即可以提高数据的可靠性,也可以提升数据的访问性能。

第三,针对磁盘和应用程序的 I/O模式的特征,可选择最适合的 I/O调度算法

第四,可以针对应用程序的数据,进行磁盘级别的隔离。比如,可以为日志、数据库等 I/O压力比较重的应用,配置单独的磁盘。

第五,在顺序读比较多的场景中,可以增大磁盘的预读数据,可以通过两种方法,调整 /dev/sdb的预读大小。一种,调整内核选项,
/sys/block/sdb/queue/read_ahead_kb,默认大小128KB。另一种,blockdev工具,比如,blockdev --setra 8192 /dev/sdb ,注意这里的单位是 512B,所以它的数值总是 read_ahead_kb的两倍。

第六,优化内核块设备 I/O的选项。比如,调整磁盘队列的长度,
/sys/block/sdb/queue/nr_requests,适当增大队列长度,可以增大磁盘的吞吐量,当然也会增大 I/O延迟。

最后,磁盘本身的硬件错误,也会导致 I/O性能急剧下降。比如,查看 dmesg中是否有硬件 I/O故障的日志,还可以使用badblocks、smartctl等工具,检测磁盘的硬件问题,或用 e2fsck等来检测文件系统错误。如果发现问题,可使用fsck 等工具修复。

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 缓存
    +关注

    关注

    1

    文章

    220

    浏览量

    26444
  • 磁盘
    +关注

    关注

    1

    文章

    338

    浏览量

    24883
  • 存储空间
    +关注

    关注

    0

    文章

    47

    浏览量

    10496
  • i/o
    i/o
    +关注

    关注

    0

    文章

    33

    浏览量

    4524
收藏 人收藏

    评论

    相关推荐

    I/O口状态切换说明

    對於普通雙向I/O 口,在位操作時出現狀態切換異常情況的分析說明:1) 普通I/O 口結構圖:結構圖2) 普通
    发表于 03-31 14:46

    新ESD技术减小芯片的I/O尺寸

    ,设计工程师必须解决I/O晶体管的尺寸问题。  另外,静电放电电流通常达到几安培,为了保证IC的性能,在芯片设计中必须引入强制性ESD保护措施,这在一定程度上加大了I/
    发表于 12-11 13:39

    8255 I/O扩展

    我用8255扩展51单片机的I/O口,A0、A1、CS分别接P2.0、P2.1、P2.7,虽然可以算出PA、PB、PC的地址,但需要对PA、PB、PC口中单独的I/O控制。能定义单独里
    发表于 03-12 11:26

    【转载】快速追踪和定位产生HardFault原因的方法

    AN0028—快速追踪和定位产生HardFault原因的方法概述在使用ARM Cortex-M 系列 MCU时(如AT32 MCU),有时会出现程序运行异常。当通过编译器在debug模式查原因
    发表于 08-17 09:44

    介绍数字I/O和逻辑分析仪的常用术语和定义

    本文介绍了数字I/O和逻辑分析仪的常用术语和定义。
    发表于 05-06 06:39

    什么是 I/O 口?I/O 具体能做什么呢

    I/O控制对于单片机而言是最基础最核心的东西,其实单片机除了模/数转换之外的事情。其他大部分的事情I/O口都能做的到。I/
    发表于 11-24 06:47

    SH79F6441 I/O用户指南

    SH79F6441是一种高速高效率 8051 可兼容单片机。在同样振荡频率下,较之传统的 8051 芯片它有着运行更快速的优越特性。 SH79F6441其 IO特性为: 42个双向I/O端口
    发表于 10-25 07:16

    SH79F6442 I/O口用户指南

    SH79F6442是一种高速高效率 8051 可兼容单片机。在同样振荡频率下,较之传统的 8051 芯片它有着运行更快速的优越特性。 SH79F6442 其 IO 特性为: 61个双向I/O端口
    发表于 10-25 08:04

    PLC I/O模块阵的解决方案

    DAC/ADC进行转换,通常为5V供电。为了保护装置,同时也为了确保能够达到要求的性能,需隔离供电轨,以抵消地移或噪声。因此,模拟I/O模块需要一个5V轨和+/-12至+/- 15V分离轨用于电压信号传输或电流环路灌/拉,与24
    发表于 11-16 07:41

    英特尔图形性能分析器:Geometry Viewer快速提示

    英特尔®图形性能分析器的Geometry Viewer快速提示
    的头像 发表于 11-12 06:48 2616次阅读

    匝间绝缘故障点的快速定位方法及测试

    分析了匝间绝缘损伤原因,应用匝间冲击试验,检测匝间绝缘。重点介绍匝间绝缘故障点的快速定位方法。
    发表于 04-13 09:12 3次下载
    匝间绝缘故障点的<b class='flag-5'>快速</b><b class='flag-5'>定位</b>方法及测试

    FFT帮你快速定位干扰信号来源

    在信号分析与处理中,FFT可以将时域信号转换至频域,以获得信号的频率结构、幅度、相位等信息。正确使用FFT功能可以帮助工程师快速定位干扰信号来源,进行故障定位
    的头像 发表于 08-27 16:56 1733次阅读
    FFT帮你<b class='flag-5'>快速</b><b class='flag-5'>定位</b>干扰信号来源

    Android异常日志快速定位分析小技巧

    Android异常日志快速定位分析小技巧
    的头像 发表于 08-09 10:06 1114次阅读
    Android异常日志<b class='flag-5'>快速</b><b class='flag-5'>定位</b><b class='flag-5'>分析</b>小技巧

    配网行波故障预警与定位装置的实地运行性能分析

    今天江苏宇拓电力科技来为大家说明一下配网行波故障预警与定位装置的实地运行性能分析
    的头像 发表于 12-22 14:18 186次阅读

    配网行波故障预警与定位装置的实地运行性能分析

    今天江苏宇拓电力科技来为大家说明一下配网行波故障预警与定位装置的实地运行性能分析。 一、引言 随着电力系统的复杂性和负荷的多样化,对配电网的稳定性和可靠性提出了更高的要求。在此背景下,配网行波故障
    的头像 发表于 12-22 14:21 263次阅读