Linux性能调优:使用strace来分析文件系统的性能问题

今天主要来介绍工具strace,并由它来组合lsof、vmstat、iostat、pidstat等工具共同分析文件系统存在的性能问题。

为什么要用这个工具?一是它安装使用比较方便、容易上手,可以通过apt install strace命令来安装,安装后直接通过 strace 命令使用,无需额外配置。再就是他们主要跟文件操作有关,我们在看磁盘I/O请求的过程时,一般出现问题最多的不是底层块设备层,反而是虚拟文件系统层,因为它面对的是各种各样的应用程序,绝大部分的I/O请求也是来源于此。

1、VFS的核心操作

虚拟文件系统(VFS)的核心操作主要包含 open、read、write、close、stat、fsync 等,它们比较集中且统一,有利于我们分析。而且通过分析这些系统调用的耗时和调用次数,我们也可以很快定位文件系统性能瓶颈。

open/close:表示打开/关闭文件,可能存在的性能问题集中在频繁打开、打开延迟等方面。

read/write:表示读写文件数据,关注性能指标集中在IOPS、吞吐量、缓冲区大小等上面。

stat/lstat/fstat:通过这几个操作可以获取文件的状态。

fsync:刷新磁盘,更新数据。可以关注一下刷新磁盘是否延迟。

除了这几个比较常用的,还有mmap内存映射和access的权限检查等,在必要时可以配合使用。

2、性能分析四步

在使用strace工具分析文件系统调用情况之前,我们需要使用一些前置工具来对系统进行分析一下是否调用这个工具来分析,才能达到更好的效果。

第一步

一般在出现问题时,我们首先要使用的工具是free,top等,查看一下系统整体运行情况。

例如,运行top -c命令

复制代码
top - 11:19:22 up 790 days, 18:52,  4 users,  load average: 0.00, 0.00, 0.00
Tasks: 136 total,   1 running,  87 sleeping,   0 stopped,   0 zombie
%Cpu(s):  6.8 us,  3.3 sy,  0.0 ni, 89.8 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
KiB Mem :  2041048 total,   428584 free,   246764 used,  1365700 buff/cache
KiB Swap: 14401532 total, 14029564 free,   371968 used.  1523972 avail Mem

  PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND                                                                
45479 root      20   0 1246604  17568   8288 S   4.7  0.9   5362:53 /usr/bin/telegraf --config /etc/telegraf/telegraf.conf                 
27426 root      20   0   41828   3548   2972 R   0.7  0.2   0:00.04 top -c                                                                 
   16 root      20   0       0      0      0 S   0.3  0.0 146:37.59 [ksoftirqd/1]                                                          
 3248 redis     20   0   53376   2088   1652 S   0.3  0.1 813:41.59 /usr/bin/redis-server 127.0.0.1:6379                                   
    1 root      20   0  119712   4544   3000 S   0.0  0.2 190:35.95 /sbin/init

大体可以判断以下几个关键信息

  • 基本负载信息,load average: 0.00, 0.00, 0.00。

  • 内核态 CPU 使用率,因为他们会反映出系统调用、进程调度等操作,指标中的3.3 sy。

  • CPU 等待 IO 完成的时间占比,也就是iowait,指标中的0.0 wa。

  • CPU 空闲率(越高说明 CPU 越空闲),指标中的89.8 id。

    如果存在I/O问题,一般情况下iowait会表现出来,数据持续超过10%,说明I/O压力比较大。如果sy的值持续超过20%,说明内核调度频繁或系统调用过多,需要进一步排查了。

第二步

若在第一步观察中,发现iowait确实挺高,说明这是一个潜在的性能瓶颈。我们再用iostat工具,看一下哪个磁盘I/O的使用率(%util)比较高,是否存在饱和度问题(队列avgqu-sz)。

复制代码
root@node:~# iostat -x -d 1
Linux 4.15.0-58-generic (cs1ahyper01n07)        11/17/2025      _x86_64_        (64 CPU)

Device:         rrqm/s   wrqm/s     r/s     w/s    rkB/s    wkB/s avgrq-sz avgqu-sz   await r_await w_await  svctm  %util
sda               0.00     7.94    0.03   14.19     0.88    98.64    14.00     0.00    0.07    0.37    0.07   0.01   0.01

有了这些基本信息后,我们再进一步排查。若磁盘使用率持续比较高,我们需要找出引起它升高的进程。

第三步

排查到这一步,可以用 pidstat 或者 iotop ,进一步观察进程的 I/O 情况。

复制代码
root@node:~# pidstat -d 1
Linux 4.15.0-58-generic (cs1ahyper01n07)        11/17/2025      _x86_64_        (64 CPU)

11:41:10 AM   UID       PID   kB_rd/s   kB_wr/s kB_ccwr/s iodelay  Command
11:41:11 AM     0      4855      0.00     29.63      0.00       0  bkunifylogbeat
11:41:11 AM     0      4893      0.00      3.70      0.00       0  exceptionbeat
11:41:11 AM     0     24244      0.00      7.41      0.00       0  qemu-system-x86
11:41:11 AM     0     38781      0.00      3.70      0.00       0  qemu-system-x86
11:41:11 AM     0     48974      0.00    459.26      0.00       0  qemu-system-x86

根据输出,我们可以很快找出kB_rd/s、kB_wr/s两个指标比较大的进程,以及这个进程的ID号。而且根据这个进程ID还可以找出所有线程ID和相关信息。

复制代码
root@node:~# ps -efT |grep 3565
root      3565  3565 14596  0 Mar04 ?        00:00:00 /usr/bin/telegraf --config /etc/telegraf/telegraf.conf
root      3565  3566 14596  0 Mar04 ?        02:01:44 /usr/bin/telegraf --config /etc/telegraf/telegraf.conf
root      3565  3567 14596  0 Mar04 ?        08:45:51 /usr/bin/telegraf --config /etc/telegraf/telegraf.conf
root      3565  3568 14596  0 Mar04 ?        08:25:29 /usr/bin/telegraf --config /etc/telegraf/telegraf.conf
root      3565  3569 14596  0 Mar04 ?        07:48:13 /usr/bin/telegraf --config /etc/telegraf/telegraf.conf
root      3565  3570 14596  0 Mar04 ?        00:00:00 /usr/bin/telegraf --config /etc/telegraf/telegraf.conf

第四步

根据上面三步我们找到的具体进程,我们就可以使用strace来具体分析它的文件调用情况了。

strace的基本用法:

例如,跟踪一个进程的所有文件操作:

复制代码
strace -e trace=file -tt -T -p <PID>

其中:

-e trace=file 只跟踪与文件操作相关的系统调用(包括文件路径作为参数的系统调用)

-tt 打印时间戳(包括微秒)

-T 选项来查看每个系统调用的耗时,然后找出耗时较长的调用

-p指定要跟踪的进程ID

其他参数:

-c 选项来统计系统调用的次数、错误和耗时

-o 输出到文件中

-f 跟踪子进程

-s 1024 显示字符串的最大长度

例如:

复制代码
root@node1:~# strace -e trace=stat -p 3442
strace: Process 3442 attached
--- SIGUSR1 {si_signo=SIGUSR1, si_code=SI_USER, si_pid=3447, si_uid=114} ---
stat("promote", 0x7ffd312ccf10)         = -1 ENOENT (No such file or directory)
stat("fallback_promote", 0x7ffd312ccf10) = -1 ENOENT (No such file or directory)
--- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=42508, si_uid=114, si_status=0, si_utime=0, si_stime=0} ---
--- SIGUSR1 {si_signo=SIGUSR1, si_code=SI_USER, si_pid=3447, si_uid=114} ---

根据第三步中查到的进程ID,我们使用strace -p来查看进程的文件调用情况。

复制代码
root@node:~# strace -e trace=read,write -p 60274
strace: Process 60274 attached
read(5, "\1\0\0\0\0\0\0\0", 512)        = 8
write(20, "\1\0\0\0\0\0\0\0", 8)        = 8
read(5, "\1\0\0\0\0\0\0\0", 512)        = 8
write(20, "\1\0\0\0\0\0\0\0", 8)        = 8
write(9, "\1\0\0\0\0\0\0\0", 8)         = 8
write(9, "\1\0\0\0\0\0\0\0", 8)         = 8
write(9, "\1\0\0\0\0\0\0\0", 8)         = 8
read(9, "\3\0\0\0\0\0\0\0", 16)         = 8
read(9, 0x7ffe9b2b8060, 16)             = -1 EAGAIN (Resource temporarily unavailable)

有时候read()、write()调用中只能看到文件的描述符编号,文件名和路径还是未知的。这时候我们还需要借助lsof,它专门用来查看进程打开文件的列表,不过,这里的"文件"不只有普通文件,还包括了目录、块设备、动态库、网络套接字等。

复制代码
root@node:~# lsof -p 60274
COMMAND     PID USER   FD      TYPE             DEVICE  SIZE/OFF       NODE NAME
qemu-syst 60274 root  cwd       DIR                8,1      4096          2 /
qemu-syst 60274 root  rtd       DIR                8,1      4096          2 /
qemu-syst 60274 root  txt       REG                8,1  22519968    1587004 /usr/bin/qemu-system-x86_64

其中,FD 表示文件描述符号,TYPE 表示文件类型,NAME 表示文件路径。

根据查到的具体文件、应用等信息就可以进一步分析具体问题了。

相关推荐
Apibro2 小时前
【LINUX】时区修改
linux·运维·服务器
槿花Hibiscus2 小时前
C++基础:session实现和http server类最终组装
服务器·c++·http·muduo
倔强的小石头_2 小时前
Python 从入门到实战(六):字典(关联数据的 “高效管家”)
java·服务器·python
阿海5742 小时前
安装nginx1.29.3的shell脚本命令
linux·nginx
徐子元竟然被占了!!2 小时前
运行yum命令出现报错:Error: rpmdb open failed
linux
进击的丸子2 小时前
跨平台人脸识别 SDK 部署指南
linux·后端·代码规范
@YDWLCloud2 小时前
出海 APP 如何降低延迟?腾讯云国际版 GME 音视频深度评测
大数据·服务器·云计算·音视频·腾讯云
Splashtop高性能远程控制软件2 小时前
索尼 Hawk-Eye(鹰眼)携手 Splashtop,远程技术赋能赛事运营革新
运维·网络·自动化·远程控制·远程桌面
九河云2 小时前
华为云 ModelArts 赋能 AI 开发:从模型训练到边缘部署的全流程优化实践
服务器·人工智能·华为云·云计算