2025年4月5日 星期六 乙巳(蛇)年 正月初六 设为首页 加入收藏
rss
您当前的位置:首页 > 计算机 > 系统应用 > Linux

Linux 磁盘IO 性能优化

时间:09-04来源:作者:点击数:38

1、什么是磁盘

在讲解磁盘IO前,先简单说下什么是磁盘。磁盘是可以持久化存储的设备,根据存储介质的不同,常见磁盘可以分为两类:机械磁盘和固态磁盘。

1.1 机械磁盘

第一类,机械磁盘,也称为硬盘驱动器(Hard Disk Driver),通常缩写为 HDD。机械磁盘主要由盘片和读写磁头组成,数据就存储在盘片的环状磁道中。在读写数据前,需要移动读写磁头,定位到数据所在的磁道,然后才能访问数据。显然,如果 I/O 请求刚好连续,那就不需要磁道寻址,自然可以获得最佳性能。这其实就是我们熟悉的,连续 I/O 的工作原理。与之相对应的,当然就是随机 I/O,它需要不停地移动磁头,来定位数据位置,所以读写速度就会比较慢。

1.2 固态磁盘

第二类,固态磁盘(Solid State Disk),通常缩写为 SSD,由固态电子元器件组成。固态磁盘不需要磁道寻址,所以,不管是连续 I/O,还是随机 I/O 的性能,都比机械磁盘要好得多。

1.3 机械磁盘和固态磁盘对比

其实,无论机械磁盘,还是固态磁盘,相同磁盘的随机 I/O 都要比连续 I/O 慢很多,原因也很明显。

对机械磁盘来说,刚刚提到过的,由于随机 I/O 需要更多的磁头寻道和盘片旋转,它的性能自然要比连续 I/O 慢。

而对固态磁盘来说,虽然它的随机性能比机械硬盘好很多,但同样存在“先擦除再写入”的限制。随机读写会导致大量的垃圾回收,所以相对应的,随机 I/O 的性能比起连续 I/O 来,也还是差了很多。

此外,连续 I/O 还可以通过预读的方式,来减少 I/O 请求的次数,这也是其性能优异的一个原因。很多性能优化的方案,也都会从这个角度出发,来优化 I/O 性能。

此外,机械磁盘和固态磁盘还分别有一个最小的读写单位。

机械磁盘的最小读写单位是扇区,一般大小为 512 字节。

而固态磁盘的最小读写单位是页,通常大小是 4KB、8KB 等。

如果每次都读写 512 字节这么小的单位的话,效率很低。所以,Linux文件系统会把连续的扇区或页,组成逻辑块,然后以逻辑块作为最小单元来管理数据。常见的逻辑块的大小是 4KB,也就是说,连续 8 个扇区,或者单独的一个页,都可以组成一个逻辑块。

1.4 按照接口进行磁盘分类1.4 按照接口进行磁盘分类

除了可以按照存储介质来分类,另一个常见的分类方法,是按照接口来分类,比如可以把硬盘分为 IDE(Integrated Drive Electronics)、SCSI(Small Computer System Interface) 、SAS(Serial Attached SCSI) 、SATA(Serial ATA) 、FC(Fibre Channel) 等。

不同的接口,往往分配不同的设备名称。比如, IDE 设备会分配一个 hd 前缀的设备名,SCSI 和 SATA 设备会分配一个 sd 前缀的设备名。如果是多块同类型的磁盘,就会按照 a、b、c 等的字母顺序来编号。

1.5 磁盘架构1.5 磁盘架构

除了磁盘本身的分类外,当你把磁盘接入服务器后,按照不同的使用方式,又可以把它们划分为多种不同的架构。

最简单的,就是直接作为独立磁盘设备来使用。这些磁盘,往往还会根据需要,划分为不同的逻辑分区,每个分区再用数字编号。比如我们前面多次用到的 /dev/sda ,还可以分成两个分区 /dev/sda1 和 /dev/sda2。

另一个比较常用的架构,是把多块磁盘组合成一个逻辑磁盘,构成冗余独立磁盘阵列,也就是 RAID(Redundant Array of Independent Disks),从而可以提高数据访问的性能,并且增强数据存储的可靠性。

根据容量、性能和可靠性需求的不同,RAID 一般可以划分为多个级别,如 RAID0、RAID1、RAID5、RAID10 等。

RAID0 有最优的读写性能,但不提供数据冗余的功能。

而其他级别的 RAID,在提供数据冗余的基础上,对读写性能也有一定程度的优化。

最后一种架构,是把这些磁盘组合成一个网络存储集群,再通过 NFS、SMB、iSCSI 等网络存储协议,暴露给服务器使用。(云服务器基本都是这种架构)

其实在 Linux 中,磁盘实际上是作为一个块设备来管理的,也就是以块为单位读写数据,并且支持随机读写。每个块设备都会被赋予两个设备号,分别是主、次设备号。主设备号用在驱动程序中,用来区分设备类型;而次设备号则是用来给多个同类设备编号。

2、什么是磁盘IO 

磁盘 I/O(Input/Output)是指计算机系统中涉及到磁盘的数据读取和写入操作。磁盘 I/O 是计算机与存储设备之间进行数据交换的一种重要方式。当计算机需要从磁盘读取数据时,它会发起一个读取请求,磁盘会寻找并将数据传输到计算机的内存中;当计算机需要将数据写入磁盘时,它会发起一个写入请求,将数据从内存写入到磁盘中。

我们都知道磁盘中存储的程序,必须要加载到内存后才能运行,在磁盘中保存的原始程序是无法直接运行的。这是因为,负责解析和运行程序内容的CPU,需要通过内部程序计数器来指定内存地址,然后才能读出程序。即使CPU可以直接读出并运行磁盘中保存的程序,由于磁盘读取速度慢,程序的运行速度还是会降低。总之,存储在磁盘中的程序需要读入到内存后才能运行。

当程序在内存中执行时,如果需要加载一些文档数据或其他文件,它会通过操作系统提供的文件操作功能来实现。操作系统会提供一些函数或系统调用,允许程序访问磁盘上的文件并将其加载到内存中。程序可以使用文件路径指定要加载的文件,然后通过操作系统提供的函数来打开这些文件。一旦文件被打开,程序就可以读取其中的数据,并将其加载到内存中,以便后续处理。这就好像你在读一本书,首先需要打开书本,然后才能阅读其中的内容。 当程序执行 I/O 操作时,CPU 将会暂时停止执行程序指令,而是会等待操作系统完成读取文件的工作。

一旦CPU下发了读取文件的指令,它会等待操作系统通知文件已经准备好,并将数据加载到内存中。CPU会继续执行其他的指令,而不是空闲等待。一旦文件数据加载到内存中,CPU 就会继续执行程序的后续逻辑。在这个过程中,CPU 可能会执行其他指令,例如处理内存中的其他数据,执行其他线程的操作,或者执行程序的其他部分逻辑。 CPU 不会在等待期间完全停止执行。

Linux 磁盘IO 性能优化,提升30%

注意 1:当CPU需要等待磁盘操作完成才能继续处理数据时,它可能会进入空闲状态,这时,CPU的使用率下降,因为它正在等待IO操作,而不是执行计算任务,这种现象说明了IO操作对CPU性能的重要影响。

注意 2:内存相当于CPU和硬盘之间的桥梁,当需要运行一个程序时,先将程序加载到内存中,然后CPU取内存中的指令和数据进行处理运算,处理完后将结果写回内存,如果需要的话再将结果从内存写入硬盘。

3、磁盘性能指标

说到磁盘性能的衡量标准,必须要提到五个常见指标,也就是我们经常用到的,使用率、饱和度、IOPS、吞吐量以及响应时间等。这五个指标,是衡量磁盘性能的基本指标:

  • IOPS(Input/Output Per Second),是指每秒磁盘处理的I/O请求数量。衡量存储性能一般看吞吐量(传输速度)和IOPS两个指标。
  • 吞吐量,是指每秒磁盘处理的 I/O 请求大小,吞吐量主要指大文件的连续读写速度,在大文件的复制、备份等场景适用,用“HD Tune专业版”中的“基准”测试功能即可测试出磁盘的吞吐量,一般传统机械sata硬盘的顺序读写速度为 :80~150M/s,SAS硬盘为150~200M/s,SSD固态硬盘为400~600M/s。
  • 响应时间,是指 I/O 请求从发出到收到响应的间隔时间。
  • 使用率,是指磁盘处理 I/O 的时间百分比。过高的使用率(比如超过 80%),通常意味着磁盘 I/O 存在性能瓶颈,这里要注意的是,使用率只考虑有没有 I/O,而不考虑 I/O 的大小。换句话说,当使用率是 100% 的时候,磁盘依然有可能接受新的 I/O 请求,比如磁盘一直读写小文件,虽然使用率是100%,但是磁盘压力可能并不大。
  • 饱和度,是指磁盘处理 I/O 的繁忙程度。过高的饱和度,意味着磁盘存在严重的性能瓶颈。当饱和度为 100% 时,磁盘无法接受新的 I/O 请求。
    这些指标,很可能是你经常挂在嘴边的,一讨论磁盘性能必定提起的对象。不过我还是要强调一点,不要孤立地去比较某一指标,而要结合读写比例、I/O 类型(随机还是连续)以及 I/O 的大小,综合来分析。举个例子,在数据库、大量小文件等这类随机读写比较多的场景中,IOPS 更能反映系统的整体性能;而在多媒体等顺序读写较多的场景中,吞吐量才更能反映系统的整体性能。
    一般来说,我们在为应用程序的服务器选型时,要先对磁盘的 I/O 性能进行基准测试,以便可以准确评估,磁盘性能是否可以满足应用程序的需求。但还是那句话,因地制宜,灵活选取。在基准测试时,一定要注意根据应用程序 I/O 的特点,来具体评估指标。当然,这就需要你测试出,不同 I/O 大小(一般是 512B 至 1MB 中间的若干值)分别在随机读、顺序读、随机写、顺序写等各种场景下的性能情况。用性能工具得到的这些指标,可以作为后续分析应用程序性能的依据。一旦发生性能问题,你就可以把它们作为磁盘性能的极限值,进而评估磁盘 I/O 的使用情况。

4、磁盘 I/O 观测

了解磁盘的性能指标,只是我们 I/O 性能测试的第一步。接下来,又该用什么方法来观测它们呢?这里,介绍几个常用的 I/O 性能观测方法。

4.1 观察每块磁盘的使用情况

iostat是I/O statistics(输入/输出统计)的缩写,iostat工具将对系统的磁盘操作活动进行监视。它的特点是汇报磁盘活动统计情况,同时也会汇报出CPU使用情况。iostat也有一个弱点,就是它不能对某个进程进行深入分析,仅对系统的整体情况进行分析。

  • # iostat属于sysstat软件包。可以直接安装。
  • yum install sysstat -y

选项说明:

  • -c: 仅显示CPU利用率相关信息;
  • -d: 仅显示磁盘I/O相关信息;
  • -k: 显示输出的数据单位为KB/s而不是默认的字节/s;
  • -t: 在输出中显示时间戳(时间戳格式YYYY-MM-DD HH:MM:SS)。
  • -m:显示状态以兆字节每秒为单位;
  • -p:仅显示块设备和所有被使用的其他分区的状态;
  • -V:显示版号并退出;
  • -x:显示扩展状态。

iostat 的详细使用本文不再赘余,详情见《Linux命令拾遗-%iowait指标代表了什么? 》这篇文章。

在iostat输出的这些指标中,需要注意:

  • %util ,就是我们前面提到的磁盘 I/O 使用率;
  • r/s+ w/s ,就是 IOPS;
  • rkB/s+wkB/s ,就是吞吐量;
  • r_await 或 w_await ,就是响应时间。

在观测指标时,也别忘了结合请求的大小( rareq-sz 和 wareq-sz)一起分析。你可能注意到,从 iostat 并不能直接得到磁盘饱和度。事实上,饱和度通常也没有其他简单的观测方法,不过,你可以把观测到的平均请求队列长度或者读写请求完成的等待时间,跟基准测试的结果(比如通过 fio)进行对比,综合评估磁盘的饱和情况。

4.2 观察进程io的使用情况

除了每块磁盘的 I/O 情况,每个进程的 I/O 情况也是我们需要关注的重点。上面提到的 iostat 只提供磁盘整体的 I/O 性能数据,缺点在于,并不能知道具体是哪些进程在进行磁盘读写。要观察进程的 I/O 情况,还可以使用iotop这个工具。iotop。它是一个类似于 top 的工具,你可以按照 I/O 大小对进程排序,然后找到 I/O 较大的那些进程。

  • #安装
  • yum -y install iotop

选项说明:

  • • --version #显示版本号
  • • -h, --help #显示帮助信息
  • • -o, --only #显示进程或者线程实际上正在做的I/O,而不是全部的,可以随时切换按o
  • • -b, --batch #运行在非交互式的模式
  • • -n NUM, --iter=NUM #在非交互式模式下,设置显示的次数,
  • • -d SEC, --delay=SEC #设置显示的间隔秒数,支持非整数值
  • • -p PID, --pid=PID #只显示指定PID的信息
  • • -u USER, --user=USER #显示指定的用户的进程的信息
  • • -P, --processes #只显示进程,一般为显示所有的线程
  • • -a, --accumulated #显示从iotop启动后每个线程完成了的IO总数
  • • -k, --kilobytes #以千字节显示
  • • -t, --time #在每一行前添加一个当前的时间
  • • -q, --quiet #suppress some lines of header (implies --batch). This option can be specified up to three times to remove header lines.
  • • -q column names are only printed on the first iteration,
  • • -qq column names are never printed,
  • • -qqq the I/O summary is never printed.
  • iotop 快捷键
  • • 左右箭头 #改变排序方式,默认是按IO排序
  • • r #改变排序顺序
  • • o #只显示有IO输出的进程
  • • p #进程/线程的显示方式的切换
  • • a #显示累积使用量
  • • q #退出

iotop 的输出如下所示:

  • $ iotop
  • Total DISK READ : 0.00 B/s | Total DISK WRITE : 7.85 K/s
  • Actual DISK READ: 0.00 B/s | Actual DISK WRITE: 0.00 B/s
  • TID PRIO USER DISK READ DISK WRITE SWAPIN IO> COMMAND
  • 15055 be/3 root 0.00 B/s 7.85 K/s 0.00 % 0.00 % systemd-journald

从这个输出,可以看到,前两行分别表示,进程的磁盘读写大小总数和磁盘真实的读写大小总数。因为缓存、缓冲区、I/O 合并等因素的影响,它们可能并不相等。剩下的部分,则是从各个角度来分别表示进程的 I/O 情况,包括线程 ID、I/O 优先级、每秒读磁盘的大小、每秒写磁盘的大小、换入和每个进程的 I/O 利用率(即进程正在进行的 I/O 操作所占用的时间比例)。

4.3 磁盘性能观测命令补充

(1)sar命令

ostat 和 iotop 命令都主要用于实时监控系统的 I/O 情况,通常不会记录历史的 I/O 信息。如果你需要查看历史的 I/O 信息,可以考虑使用sar命令。

sar 命令是分析系统瓶颈的神器,可以用来查看 CPU 、内存、磁盘、网络等性能,sar 命令查看当前磁盘性能的命令为:

  • [root@106 sa]# sar -d -p 1 2
  • Linux 3.10.0-1160.59.1.el7.x86_64 (106) 2024年04月18日 _x86_64_ (8 CPU)
  • 17时33分33秒 DEV tps rd_sec/s wr_sec/s avgrq-sz avgqu-sz await svctm %util
  • 17时33分34秒 sdc 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
  • 17时33分34秒 sdd 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
  • 17时33分34秒 sdb 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
  • 17时33分34秒 sda 25.00 0.00 276.00 11.04 0.00 0.16 0.16 0.40
  • 17时33分34秒 centos-root 25.00 0.00 276.00 11.04 0.00 0.16 0.16 0.40
  • 17时33分34秒 centos-swap 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
  • 17时33分34秒 DEV tps rd_sec/s wr_sec/s avgrq-sz avgqu-sz await svctm %util
  • 17时33分35秒 sdc 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
  • 17时33分35秒 sdd 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
  • 17时33分35秒 sdb 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
  • 17时33分35秒 sda 153.00 0.00 1444.00 9.44 0.85 5.55 0.29 4.40
  • 17时33分35秒 centos-root 153.00 0.00 1444.00 9.44 0.85 5.54 0.29 4.40
  • 17时33分35秒 centos-swap 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
  • 平均时间: DEV tps rd_sec/s wr_sec/s avgrq-sz avgqu-sz await svctm %util
  • 平均时间: sdc 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
  • 平均时间: sdd 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
  • 平均时间: sdb 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
  • 平均时间: sda 89.00 0.00 860.00 9.66 0.43 4.79 0.27 2.40
  • 平均时间: centos-root 89.00 0.00 860.00 9.66 0.43 4.79 0.27 2.40
  • 平均时间: centos-swap 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
  • [root@106 sa]#

其中, “-d”参数代表查看磁盘性能,“-p”参数代表将 dev 设备按照 sda,sdb……名称显示,“1”代表每隔1s采取一次数值,“2”代表总共采取2次数值。输出项除了tps,其他指标和iostat一致,这里就不再赘余(tps:每秒钟物理设备的 I/O 传输总量)。

默认情况下,sar显示当前数据;如果想继续查看一天前的报告;可以查看保存在/var/log/sa/下的sar日志(默认保存三天数据):

  • [root@106 sa]# sar -d -p -f /var/log/sa/sa16
  • Linux 3.10.0-1160.59.1.el7.x86_64 (106) 2024年04月16日 _x86_64_ (8 CPU)
  • 14时10分01秒 DEV tps rd_sec/s wr_sec/s avgrq-sz avgqu-sz await svctm %util
  • 14时20分01秒 sdc 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
  • 14时20分01秒 sdd 0.04 0.00 0.36 9.00 0.00 2.12 2.12 0.01
  • 14时20分01秒 sdb 0.01 0.00 0.12 9.00 0.00 0.38 0.38 0.00
  • 14时20分01秒 sda 49.17 0.00 888.31 18.07 0.07 1.41 0.58 2.85
  • 14时20分01秒 centos-root 49.42 0.00 888.30 17.97 0.07 1.43 0.58 2.85
  • ......
  • 23时40分01秒 sdc 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
  • 23时40分01秒 sdd 0.04 0.00 0.36 9.00 0.00 0.79 0.79 0.00
  • 23时40分01秒 sdb 0.01 0.00 0.12 9.00 0.00 1.62 1.62 0.00
  • 23时40分01秒 sda 48.50 0.00 892.42 18.40 0.08 1.57 0.63 3.07
  • 23时40分01秒 centos-root 48.71 0.00 892.42 18.32 0.08 1.58 0.63 3.07
  • 23时40分01秒 centos-swap 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
  • 23时50分01秒 sdc 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
  • 23时50分01秒 sdd 0.04 0.00 0.36 9.00 0.00 0.25 0.25 0.00
  • 23时50分01秒 sdb 0.01 0.00 0.12 9.00 0.00 0.25 0.25 0.00
  • 23时50分01秒 sda 49.29 0.00 824.63 16.73 0.07 1.52 0.64 3.18
  • 23时50分01秒 centos-root 49.50 0.00 824.63 16.66 0.08 1.53 0.64 3.18
  • 23时50分01秒 centos-swap 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
  • 平均时间: sdc 0.00 0.47 0.01 208.69 0.00 4.06 2.78 0.00
  • 平均时间: sdd 0.04 0.00 0.37 9.08 0.00 0.49 0.48 0.00
  • 平均时间: sdb 0.02 0.00 0.14 9.31 0.00 0.53 0.50 0.00
  • 平均时间: sda 48.53 0.00 863.51 17.79 0.07 1.46 0.61 2.97
  • 平均时间: centos-root 48.74 0.00 863.51 17.71 0.07 1.47 0.61 2.97
  • 平均时间: centos-swap 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00

(2)其他IO相关的常用命令

Linux 磁盘IO 性能优化,提升30%

5、小结

本文梳理了磁盘、 Linux IO、IO性能指标和性能工具。我们通常用 IOPS、吞吐量、使用率、饱和度以及响应时间等几个指标,来评估磁盘的 I/O 性能。可以用 iostat 获得磁盘的 I/O 情况,也可以用iotop 观察进程的 I/O 情况。不过在分析这些性能指标时,要注意结合读写比例、I/O 类型以及 I/O 大小等,进行综合分析。

方便获取更多学习、工作、生活信息请关注本站微信公众号城东书院 微信服务号城东书院 微信订阅号
推荐内容
相关内容
栏目更新
栏目热门
本栏推荐