文件 IO 性能监控:深度分析与实用技巧

文摘   2024-11-18 09:00   广东  

点击上方【蓝字】关注博主

 文件IO性能的监控与优化是确保系统高效运行的重要环节。通过对文件读写速度、传输次数、等待时间等关键性能指标的监测,能够全面了解系统的I/O状况,从而识别潜在的瓶颈和问题。

01

简介

文件IO主要考虑以下几个点:

  1. 文件写入速度。

  2. 文件读取速度。

  3. 写入扇区的次数。

  4. 读取扇区的次数。

  5. IO 等待时间:时间越大说明文件操作频繁。

磁盘的统计参数:
  • tps:该设备每秒的传输次数(Indicate the number of transfers per second that were issued to the device.)。“一次传输"意思是"一次I/O请求”。多个逻辑请求可能会被合并为"一次I/O请求"。"一次传输"请求的大小是未知的。

  • kB_read/s每秒从设备(drive expressed)读取的数据量;

  • kB_wrtn/s每秒向设备(drive expressed)写入的数据量;

  • kB_read读取的总数据量;

  • kB_wrtn写入的总数量数据量;这些单位都为Kilobytes

系统调用、VFS、缓存、文件系统以及块存储之间的关系如下图所示:

从图上可以看到,Buffer 是离磁盘更近的缓冲区,而 Cache 则是跟接近用户空间。

Linux 内核在用户进程和文件系统的中间,又引入了一个抽象层,也就是虚拟文件系统 VFS(Virtual File System)。

I/O 指的是相对内存而言的 input 和 output。从文件、数据库、网络向内存中写入数据叫做 input;从内存向文件、数据库、网络中输出数据叫做 output。Linux 系统 I/O 分为内核准备数据将数据从内核拷贝到用户空间两个阶段。

02

I/O 的两种方式

2.1、缓存 I/O

缓存 I/O 又被称作标准 I/O,大多数文件系统的默认 I/O 操作都是缓存 I/O。在 Linux 的缓存 I/O 机制中,数据先从磁盘复制到内核空间的缓冲区,然后从内核空间缓冲区复制到应用程序的地址空间(用户空间)。即缓存 I/O 可以理解为内核空间缓存区。

  • 读操作:根据局部性原理,操作系统检查内核空间的缓冲区有没有需要的数据,如果已经缓存了,那么就直接从缓存中返回,也就是将数据复制到应用程序的用户空间;否则从磁盘中读取数据至内核空间的缓冲区,再将内核空间缓冲区的数据返回。

  • 写操作将数据从用户空间复制到内核空间的缓冲区,这时对用户程序来说写操作就已经完成。至于什么时候将数据从内核空间写到磁盘中,这步由操作系统决定,除非显示地调用了 sync 同步命令。

缓存 I/O 的优点:
  1. 在一定程度上分离了内核空间和用户空间,保护系统本身的运行安全;

  2. 可以减少读盘的次数,从而提高性能。

缓存 I/O 的缺点: 在缓存 I/O 机制中,DMA 方式可以将数据直接从磁盘读到内核空间的页缓存中,或者将数据从内核空间的页缓存中直接写回到磁盘上,而不能直接在应用程序地址空间(用户空间)和磁盘之间进行数据传输。这样,数据在传输过程中需要在应用程序地址空间(用户空间)和页缓存(内核空间)之间进行多次数据拷贝操作,这些数据拷贝操作所带来的 CPU 以及内存开销是比较大的。

2.2、直接 I/O

直接 IO 就是应用程序直接访问磁盘,而不经过内核缓冲区,这样做的目的是减少一次从内核缓冲区到用户程序地址空间的数据复制操作。
例如数据库管理系统这类应用,它们更倾向于选择自己的缓存机制,因为数据库管理系统往往比操作系统更了解数据库中存放的数据。数据库管理系统可以提供一种更加高效的缓存机制来提高数据库中存取数据的性能。

直接IO的方式非常适合做文件高性能传输。,比如分布式文件存储。

03

监控磁盘I/O的命令

3.1、iostat 监控IO状态

该命令用于监控CPU占用率、平均负载值及I/O读写速度等。
参数介绍:

iostat [ -c ] [ -d ] [ -h ] [ -N ] [ -k | -m ] [ -t ] [ -V ] [ -x ] [ -z ] [ device [...] | ALL ] [ -p [ device [,...] | ALL ] ] [ interval [ count ] ]

常用参数:

选项描述
-c输出 CPU 统计信息
-d输出磁盘统计信息。注:默认是两个都输出
-k、-m以 KB/s 或 MB/s 代替原来的块/s
-t输出时打印收集信息时刻的时间。注:时间的打印格式和系统变量 S_TIME_FORMAT 相关
-x输出详细的拓展统计数据,比如各种等待时间、队列、利用率等信息
interval [count]interval是统计的时间间隔,单位是 s,count 则是统计次数

示例:

[root@VM_0_ubuntu ~]# iostat -x

Device: rrqm/s wrqm/s r/s w/s rkB/s wkB/s avgrq-sz avgqu-sz await r_await w_await svctm %util
loop0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
sda 0.00 80.00 5.00 1152.00 20.00 935160.00 1616.56 2.74 2.96 1.60 2.97 0.74 85.20

Device: rrqm/s wrqm/s r/s w/s rkB/s wkB/s avgrq-sz avgqu-sz await r_await w_await svctm %util
loop0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
sda 0.00 80.00 15.00 1137.00 852.00 1049236.00 1823.07 2.30 2.59 1.07 2.61 0.72 82.80

每个输出消息含义:

输出消息含义
rrqm/s每秒对该设备的读请求被合并次数,文件系统会对读取同块(block)的请求进行合并
wrqm/s每秒对该设备的写请求被合并次数
r/s每秒完成的读次数
w/s每秒完成的写次数
rkB/s每秒读数据量 (以 kB 为单位)
wkB/s每秒写数据量 (以 kB 为单位)
avgrq-sz平均每次 IO 操作的数据量 (扇区数为单位),例如 1616.56
avgqu-sz平均等待处理的 IO 请求队列长度,例如 2.74
await平均每次 IO 请求等待时间 (包括等待时间和处理时间,毫秒为单位),例如 w_await 2.97
svctm平均每次 IO 请求的处理时间 (毫秒为单位),例如 0.72
%util采用周期内用于 IO 操作的时间比率,即 IO 队列非空的时间比率,表示设备的繁忙程度,例如 82.80。例如,如果统计间隔 1 秒,该设备有 0.5 秒在处理 IO,而 0.5 秒闲置,则该设备的 %util = 0.5/1 = 50%。一般地,如果该参数是 100% 表示设备已经接近满负荷运行。

await指的是平均等待时间,一般都在10ms左右。关于 awaitsvctm:可以理解为IO请求的响应时间,包括队列等待时间和服务时间,我们分析IO问题时,如果await大于svctmawait-svctm差值越小,则说明队列时间越短, 反之差值越大,队列时间越长,说明磁盘io有性能问题。

可以看到,这个工具虽然能够监控磁盘IO的状态,但是并不知道是哪个进程在进行磁盘IO操作,因此,可以结合pidstat -d命令使用。

cpu的统计信息,如果是多cpu系统,显示的所有cpu的平均统计信息。

输出消息含义
%user用户进程消耗 CPU 的比例
%nice用户进程优先级调整消耗的 CPU 比例
%sys系统内核消耗的 CPU 比例
%iowait等待磁盘 IO 所消耗的 CPU 比例
%idle闲置 CPU 的比例(不包括等待磁盘 I/O)

常用用法:

# kb/s显示磁盘信息,每2s刷新一次
iostat -d -k 2

# kb/s显示磁盘统计信息及扩展信息,每1s刷新 ,刷新10次结束
iostat -dkx 1 10

3.2、swapon 查看分区使用情况

swapon 是 Linux 系统中用于启用交换空间(swap space)的命令。交换空间是硬盘上的一块区域,允许系统使用其作为虚拟内存,以应对物理内存不足的情况。

命令语法:

swapon [OPTIONS] [FILE | DEVICE...]

常用选项:

选项含义
-a--all启用在 /etc/fstab 文件中标记为交换空间的所有交换分区和文件。
-e--show-header在输出时显示标题行。
-h--help显示帮助信息并退出。
-s--summary显示当前交换空间的摘要信息。
-p--priority PRIO设置交换空间的优先级。优先级越高,系统更倾向于使用优先级高的交换空间。优先级值范围通常为 -1 至 32767。

示例:

  1. 启用交换文件或分区

    sudo swapon /dev/sdX
  2. 启用多个交换设备

    sudo swapon /dev/sdX /dev/sdY
  3. 启用所有在 fstab 中配置的交换空间

    sudo swapon -a
  4. 查看当前的交换空间状态

    [root@VM_0_ubuntu ~]# swapon -s

    Filename Type Size Used Priority

    /var/swap file 8191996 473856 -2
  5. 查看详细的内存与交换信息:free 命令显示系统内存的使用情况,包括交换空间信息。

    free -h

注意:

  • 通常在系统启动时,交换空间会自动启用,因此一般用户不会频繁使用 swapon 命令。

  • 在使用 swapon 启用交换空间前,确保交换分区或文件已经创建并格式化。

  • 使用 swapoff 命令可以禁用交换空间。

我们在安装系统的时候已经建立了 swap 分区。swap 分区通常被称为交换分区,这是一块特殊的硬盘空间,即当实际内存不够用的时候,操作系统会从内存中取出一部分暂时不用的数据,放在交换分区中,从而为当前运行的程序腾出足够的内存空间。也就是说,当内存不够用时,我们使用 swap 分区来临时顶替。这种“拆东墙,补西墙”的方式应用于几乎所有的操作系统中

一般来讲,swap 分区容量应大于物理内存大小,建议是内存的两倍,但不超过 2GB。

3.3、df 查看硬盘使用情况

df 命令用于查看文件系统的硬盘挂载点和空间使用情况,包括文件系统的总容量、已用空间、可用空间等信息。

常见选项:

选项含义
-a--all显示所有文件系统,包括 0 字节的文件系统。
-h--human-readable以人类可读的格式显示大小(例如:KB、MB、GB)。
-i--inodes显示 inode 使用情况,而不是磁盘块使用情况。
-k以 KiB(千字节)为单位显示大小。
-m以 MiB(兆字节)为单位显示大小。
--output自定义输出格式,可以指定要显示的字段。
-t--type=TYPE仅显示指定类型的文件系统(例如:ext4、ntfs 等)。
-x--exclude-type=TYPE不显示指定类型的文件系统。
-l--local仅显示本地文件系统,忽略网络文件系统。
--sync显示时对文件系统进行同步。
-P--portability以一种适合于脚本的方式输出信息,所有输出都在一行内显示。
--help显示帮助信息并退出。
--version显示版本信息并退出。

示例:

fly@LAPTOP-V34UPA81:~$ df -h
Filesystem Size Used Avail Use% Mounted on
drivers 246G 170G 76G 70% /usr/lib/wsl/drivers
/dev/sdc 1007G 4.9G 951G 1% /
rootfs 1.9G 2.2M 1.9G 1% /init
tmpfs 4.0M 0 4.0M 0% /sys/fs/cgroup

3.4、du 查看目录文件大小

du 命令用于报告文件和目录的磁盘使用情况。它可以查看各个文件和目录占用了多少磁盘空间。

常见选项:

选项含义
-a--all显示所有文件和目录的磁盘空间使用情况,包含普通文件。还要显示其下目录和文件占用磁盘空间的大小
-h--human-readable以人类可读的格式显示大小(例如:KB、MB、GB)。
-s--summarize仅显示每个参数的总计信息,不显示子目录的信息。
-c--total显示所有指定文件和目录的总计信息。还要统计它们的总和。
-d--max-depth=N限制输出的目录深度,仅显示 N 层目录。
-k以 KiB(千字节)为单位显示大小。
-m以 MiB(兆字节)为单位显示大小。
-L--dereference计算符号链接所指向的文件或目录的大小,而不是链接本身。
-0以 null 字符分隔输出,适合与其他程序结合使用(如 find)。
--exclude=PATTERN排除匹配指定模式的文件或目录。
--help显示帮助信息并退出。
--version显示版本信息并退出。

使用示例:

# 查看当前目录及其子目录的使用情况:
du

# 仅查看当前目录的总使用情况:
du -sh

# 查看指定目录的详细使用情况:
du -h /path/to/directory

# 限制输出的目录深度为 1:
du -h --max-depth=1

# 计算符号链接所指向的文件的大小:
du -hL

输出示例:

[root@VM]$ du -lh --max-depth=1
6.1M ./php
11M ./ios
146M ./server
6.6M ./pb
723M ./auto_setup
29M ./android
133M ./win-client
18M ./mac
8.0K ./tutorial
28K ./doc
99M ./.git
1.2G .
04

文件IO写入频繁案例

首先,启动 iostat -x 命令用于监测系统I/O性能,特别是针对各个磁盘设备的读写情况。这是一个非常重要的步骤,可以实时观察在执行存储性能测试时磁盘的负载情况。

iostat -dkx 1 30

-d 表示设备统计,-k 表示使用千字节为单位,-x 表示扩展统计信息,后面的 1 30 则指示系统每秒输出一次统计信息,持续30秒。在这个过程中,输出的信息将包括设备的请求数、吞吐量、平均等待时间、服务时间等。

接下来,使用 sysbench 工具模拟数据的读写操作。sysbench 是一个广泛使用的基准测试工具,可以针对多种应用场景进行性能测试。sysbench 的性能测试都需要做三步基本操作:preparerun 和 cleanup。在准备阶段,软件会创建测试所需的数据文件。在测试阶段,工具会执行读写操作,以评估存储系统的性能。最后,在清理阶段,所有测试数据必须被删除,以保证环境的整洁和后续测试的准确性。

首先进入待测试的磁盘目录。

cd /data/disktest

然后,执行性能测试的命令,例如设置线程数为4,每隔4秒输出一次结果,测试时间设定为60秒,文件数为10,文件总大小为10G,同时采用随机读写的操作模式。

sysbench --num-threads=4  --max-time=60 --test=fileio --file-num=10 --file-total-size=10G --file-test-mode=rndrw prepare

sysbench --num-threads=4 --max-time=60 --test=fileio --file-num=10 --file-total-size=10G --file-test-mode=rndrw run

sysbench --num-threads=4 --max-time=60 --test=fileio --file-num=10 --file-total-size=10G --file-test-mode=rndrw cleanup

输出的示例:

fly@ubuntu:~$ iostat -dkx 1 30
Device: rrqm/s wrqm/s r/s w/s rkB/s wkB/s avgrq-sz avgqu-sz await r_await w_await svctm %util
loop0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
sda 0.00 80.00 5.00 1152.00 20.00 935160.00 1616.56 2.74 2.96 1.60 2.97 0.74 85.20

Device: rrqm/s wrqm/s r/s w/s rkB/s wkB/s avgrq-sz avgqu-sz await r_await w_await svctm %util
loop0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
sda 0.00 80.00 15.00 1137.00 852.00 1049236.00 1823.07 2.30 2.59 1.07 2.61 0.72 82.80

Device: rrqm/s wrqm/s r/s w/s rkB/s wkB/s avgrq-sz avgqu-sz await r_await w_await svctm %util
loop0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
sda 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00


05

总结

在现代计算机系统中,文件IO性能的监控与优化是确保系统高效运行的重要环节。通过对文件读写速度、传输次数、等待时间等关键性能指标的监测,能够全面了解系统的I/O状况,从而识别潜在的瓶颈和问题。

掌握 iostat 等工具的使用,使得用户能够实时监测磁盘I/O性能,及时获取每秒传输次数、读写速率、平均等待时间等信息。

理解缓存I/O与直接I/O的概念和适用场景,是优化文件IO性能的关键因素。缓存I/O在大多数情况下能提供更高的性能,但在特定应用,如数据库管理系统中,直接I/O的优势不可忽视。

定期使用各种监控命令(如 iostatdfdu等),并结合系统负载和应用需求,进行全面的性能评估,是确保运行效率和稳定性的有效策略。

公众号: Lion 莱恩呀

微信号: 关注获取

扫码关注 了解更多内容

点个 在看 你最好看


Lion 莱恩呀
专注分享高性能服务器后台开发技术知识,涵盖多个领域,包括C/C++、Linux、网络协议、设计模式、中间件、云原生、数据库、分布式架构等。目标是通过理论与代码实践的结合,让世界上看似难以掌握的技术变得易于理解与掌握。
 最新文章