一文搞懂磁盘 I/O,基础扫盲来了!

计算机的运行,宛如一场井然有序的交响乐演出,CPU、内存、磁盘等硬件宛如乐团中的乐手,各自承担独特职责,共同演绎出和谐的乐章。在这场精彩演奏里,磁盘I/O虽不像CPU那样备受瞩目,却肩负着举足轻重的使命。它恰似一座桥梁,连接着计算机的内部天地与外部存储,专职负责数据的输入与输出。从轻松打开一份文档,到流畅加载一款大型游戏,再到服务器高效处理海量数据,每一项操作都离不开磁盘I/O的默默支撑。

然而,你可曾心生疑惑:为何有时打开一个文件转瞬即就,有时却要漫长等待?为何同样作为存储设备,固态硬盘与机械硬盘的读写速度竟有云泥之别?磁盘I/O的背后,究竟隐匿着怎样的秘密?

接下来,让我们一同深入探寻磁盘I/O的奇妙世界,揭开它神秘的面纱,了解其工作原理、性能指标,以及影响它的关键因素,让你对计算机的存储系统拥有全新的认识。

一、磁盘I/O是什么?

磁盘属于能够持久化存储的设备。依据存储介质的差异,常见磁盘可分为两类:机械磁盘与固态磁盘。

(一)机械磁盘

机械磁盘,又称硬盘驱动器(Hard Disk Driver,缩写为HDD)。它主要由盘片和读写磁头构成,数据存储于盘片的环状磁道之中。在读写数据前,需移动读写磁头,定位到数据所在磁道,方可访问数据。显然,若I/O请求刚好连续,便无需磁道寻址,自然能获取最佳性能,这正是我们所熟知的连续I/O的工作原理。与之对应的是随机I/O,它需要频繁移动磁头来定位数据位置,所以读写速度相对较慢。

(二)固态磁盘

固态磁盘(Solid State Disk,缩写为SSD)由固态电子元器件组成。由于它无需磁道寻址,因此无论是连续I/O还是随机I/O的性能,都远优于机械磁盘。

实际上,无论是机械磁盘还是固态磁盘,同一磁盘的随机I/O速度都比连续I/O慢得多,原因显而易见:

  • 对于机械磁盘而言,正如前文所述,随机I/O需要更多的磁头寻道和盘片旋转,其性能自然逊于连续I/O。
  • 对于固态磁盘来说,尽管其随机性能比机械硬盘出色许多,但同样存在“先擦除再写入”的限制。随机读写会引发大量垃圾回收,所以相对而言,随机I/O的性能较连续I/O要差不少。
  • 此外,连续I/O还能借助预读方式,减少I/O请求次数,这也是其性能卓越的原因之一。许多性能优化方案也会从这一角度着手,来提升I/O性能。

另外,机械磁盘和固态磁盘各自存在最小读写单位:

  • 机械磁盘的最小读写单位是扇区,一般大小为512字节。
  • 固态磁盘的最小读写单位是页,常见大小为4KB、8KB等。

若每次都读写512字节这般小的单位,效率会十分低下。所以,文件系统会将连续的扇区或页组合成逻辑块,并以逻辑块作为最小单元管理数据。常见的逻辑块大小为4KB,即连续8个扇区或单独1个页,均可组成一个逻辑块。

磁盘除了按存储介质分类,另一种常见分类方式是按接口分类,比如可将硬盘分为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等字母顺序编号。

除磁盘本身的分类外,当把磁盘接入服务器后,依据不同使用方式,又可将其划分为多种架构:

  • 最简单的是直接作为独立磁盘设备使用。这些磁盘往往还会按需划分为不同的逻辑分区,每个分区用数字编号。例如前文多次提及的/dev/sda,还能分成两个分区/dev/sda1和/dev/sda2。
  • 另一种常用架构是将多块磁盘组合成一个逻辑磁盘,构建冗余独立磁盘阵列,即RAID(Redundant Array of Independent Disks),以此提升数据访问性能,增强数据存储可靠性。根据容量、性能和可靠性需求的不同,RAID一般可划分为多个级别,如RAID0、RAID1、RAID5、RAID10等:
    • RAID0具备最优读写性能,但不提供数据冗余功能。
    • 其他级别的RAID在提供数据冗余的基础上,对读写性能也有一定程度的优化。
  • 最后一种架构是将这些磁盘组合成一个网络存储集群,再通过NFS、SMB、iSCSI等网络存储协议,提供给服务器使用。

在Linux系统中,磁盘实际上作为块设备进行管理,即以块为单位读写数据,且支持随机读写。每个块设备都会被赋予两个设备号,分别为主设备号和次设备号。主设备号用于驱动程序,以区分设备类型;次设备号则用于为多个同类设备编号。

简言之,磁盘I/O就是计算机与磁盘之间进行数据输入和输出的过程。当你在电脑上保存一个文档时,这便是数据输出(写入)到磁盘的操作;当你打开这个文档时,就是从磁盘输入(读取)数据到计算机内存的过程。磁盘宛如一个仓库,而I/O操作则如同货物进出仓库的搬运工作。

二、磁盘的结构与工作原理

我们可将Linux存储系统的I/O栈,自上至下划分为三个层次,分别是文件系统层、通用块层和设备层。这三个I/O层的关系如下图所示,此图实际上呈现的是Linux存储系统的I/O栈全景图:

借助这张I/O栈全景图,我们能够更清晰地理解存储系统I/O的工作原理:

  • 文件系统层:涵盖虚拟文件系统以及其他各类文件系统的具体实现。它为上层应用程序提供标准的文件访问接口,向下则通过通用块层存储和管理磁盘数据。
  • 通用块层:包含块设备I/O队列和I/O调度器。它会对文件系统的I/O请求进行排队,经过重新排序和请求合并后,才将其发送给下一级的设备层。
  • 设备层:由存储设备及其相应的驱动程序构成,负责执行最终物理设备的I/O操作。

存储系统的I/O,通常是整个系统中速度最慢的环节。为此,Linux采用多种缓存机制来优化I/O效率。例如,为提升文件访问性能,会运用页缓存、索引节点缓存、目录项缓存等多种缓存机制,以此减少对下层块设备的直接调用。同样,为优化块设备的访问效率,会利用缓冲区来缓存块设备的数据。

  • 平时调用write时,数据从应用写入到C标准库的IO Buffer(用户态),该Buffer位于应用内存中,一旦应用崩溃,数据便会丢失。
  • 在关闭流之前调用flush,可通过flush将数据主动写入到内核的Page Cache中,此时即便应用挂掉,数据依然安全(处于内核态),但如果系统崩溃,数据仍会丢失。
  • 要将内核中Page Cache的数据写入到磁盘(缓存)中,确保系统崩溃时数据不丢失,则需要调用fsync(持久化介质)。

总体而言,这体现了操作系统的多级缓存机制以及数据的可用性。操作系统本质上也是程序,借助多线程、异步以及多级缓存实现高性能。

三、磁盘I/O的性能指标

机械硬盘在连续读写方面性能表现出色,但随机读写性能欠佳。这主要是因为磁头移动到正确磁道需要耗费时间,在随机读写时,磁头需频繁移动,大量时间浪费在磁头寻址上,所以性能不高。衡量磁盘性能的重要指标主要是IOPS和吞吐量。

(1)吞吐量

吞吐量(Throughput)指的是单位时间内能够成功传输的数据量。对于顺序读写频繁的应用,如视频点播,关注连续读写性能时,数据吞吐量是关键衡量指标。它主要取决于磁盘阵列的架构、通道大小以及磁盘数量。不同的磁盘阵列具有不同架构,不过它们都有自身的内部带宽,一般情况下,内部带宽设计得较为充足,不会形成瓶颈。磁盘阵列与服务器之间的数据通道对吞吐量影响显著,例如一个2Gbps的光纤通道,其所能承载的最大流量仅为250MB/s。最后,在前面不存在瓶颈的情况下,硬盘数量越多,吞吐量越大。

(2)IOPS

IOPS(Input/Output Per Second)即每秒的输入输出量(或读写次数),指每秒内系统能够处理的I/O请求数量。对于随机读写频繁的应用,如小文件存储等,关注随机读写性能时,IOPS是关键衡量指标。我们可以推算出磁盘的IOPS = 1000ms / (Tseek + Trotation + Transfer),若忽略数据传输时间,理论上能够计算出随机读写的最大IOPS。常见磁盘的随机读写最大IOPS如下:

  • 7200rpm的磁盘IOPS = 76 IOPS
  • 10000rpm的磁盘IOPS = 111 IOPS
  • 15000rpm的磁盘IOPS = 166 IOPS

(3)响应时间

响应时间是指从发出I/O请求到收到响应的时间间隔。它涵盖了寻道时间(机械硬盘)、旋转延迟(机械硬盘)以及数据传输时间等。响应时间越短,用户体验就越好,比如文件打开速度会更快。

四、影响磁盘I/O的性能因素

Linux磁盘I/O性能受到诸多因素的综合影响,其中涵盖硬件设备、文件系统、系统配置以及应用程序的I/O模式等方面。以下为您详细介绍一些主要的影响因素:

(1)硬件设备

硬件构成了磁盘I/O性能的基石,其包含硬盘的类型(HDD或SSD)、转速、缓存大小以及接口类型(如SATA、NVMe)等要素。通过以下命令可查看磁盘信息:

# 查看磁盘信息
lsblk

(2)文件系统

文件系统的选择与配置对I/O性能有着显著影响。在Linux中,EXT4、XFS和Btrfs是常用的文件系统,它们各自具备独特的特性与最佳适用场景。运用以下命令能够查看文件系统类型:

# 查看文件系统类型
df -T

(3)系统配置

Linux内核参数、I/O调度器、文件系统的挂载选项等系统配置内容,均会对磁盘I/O性能产生作用。利用以下命令可查看当前I/O调度器:

# 查看当前I/O调度器
cat /sys/block/sda/queue/scheduler

(4)应用程序I/O模式

应用程序的I/O模式,包括I/O大小、读写比例、同步与异步I/O等,同样会对磁盘I/O性能造成影响。以下是C语言中同步和异步I/O的简单比较示例代码:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int main() {
    // 同步I/O操作
    FILE *fp = fopen("testfile", "w+");
    fprintf(fp, "Data to write");
    fclose(fp);

    // 异步I/O操作(在此示例中仅示意,实际实现更复杂)
    //...

    return 0;
}

五、磁盘I/O性能评估工具

为精确评估磁盘I/O性能,挑选恰当的工具至关重要。以下为您介绍一些常用的磁盘I/O性能评估工具及其使用方式:

(1)iostat

iostat是一款用于监控系统输入/输出设备和CPU使用情况的工具,能够提供磁盘读写速度、I/O操作次数等关键性能指标。在CentOS系统中,安装及使用iostat的方法如下:

# 安装iostat(以CentOS为例)
sudo yum install sysstat

# 使用iostat查看磁盘I/O性能
iostat -mx 1

(2)iotop

iotop是一个用于监视I/O使用情况的工具,可显示哪些进程正在使用磁盘以及它们的I/O速率。在CentOS系统中,安装及使用iotop的步骤如下:

# 安装iotop(以CentOS为例)
sudo yum install iotop

# 使用iotop监视I/O使用情况
iotop -o

(3)dd

dd是一款经典的命令行工具,用于复制文件并对数据进行转换和格式化。它同样可用于测试磁盘的读写性能。使用dd命令测试读写性能的示例如下:

# 使用dd命令测试写性能
dd if=/dev/zero of=testfile bs=1M count=1024 oflag=dsync

# 使用dd命令测试读性能
dd if=testfile of=/dev/null bs=1M count=1024 iflag=nocache

(4)fio

fio是一款灵活的I/O测试工具,能够生成各类不同类型的负载,以测试磁盘的I/O性能。使用fio进行磁盘I/O测试的示例命令如下:

# 使用fio进行磁盘I/O测试
fio --name=test --ioengine=libaio --iodepth=4 --rw=readwrite --bs=4k --size=1G --numjobs=1

借助这些工具,能够收集磁盘I/O性能的相关数据,为后续的性能优化提供有力依据。应用程序在执行I/O操作时,可采用异步I/O、缓存等技术,以减少I/O等待时间,提升整体性能。

六、磁盘缓存与I/O缓存策略

磁盘缓存和I/O缓存策略是提升磁盘I/O性能的关键途径。合理配置并运用缓存,能够大幅降低磁盘的物理读写次数,有效加快数据访问速度。

6.1 磁盘缓存

磁盘缓存处于硬盘与内存之间,是一个小容量的高速存储区域,它能够临时存储频繁被访问的数据,以此减少对硬盘的访问频次。

(1)启用磁盘缓存

大多数现代硬盘都自带内置缓存,一般情况下,操作系统会自动对这些缓存进行管理。不过,在某些特定情形下,管理员可能需要对缓存策略加以调整。

# 查看磁盘缓存策略
hdparm -c /dev/sda

# 启用磁盘缓存(对于支持此功能的硬盘)
hdparm -W 1 /dev/sda

(2)监控磁盘缓存效果

对磁盘缓存效果进行监控,有助于管理员深入了解缓存的使用状况以及性能的改进程度。

# 使用iostat监控磁盘缓存命中率
iostat -dx 1

6.2 I/O缓存策略

I/O缓存策略主要涉及操作系统如何利用内存作为缓存,来优化磁盘I/O操作。Linux系统提供了多种机制用于管理I/O缓存。

(1)调整文件系统缓存

通过对vm.dirty_ratio和vm.dirty_background_ratio参数进行调整,能够控制文件系统缓存的大小以及写入策略。

# 查看当前缓存参数
cat /proc/sys/vm/dirty_ratio
cat /proc/sys/vm/dirty_background_ratio

# 调整缓存参数
echo 20 > /proc/sys/vm/dirty_ratio
echo 10 > /proc/sys/vm/dirty_background_ratio

(2)使用直接I/O

直接I/O允许应用程序绕开操作系统缓存,直接向磁盘写入数据。在一些特定场景中,这能够提升性能,但同时也会增大磁盘I/O的压力。

# 使用dd命令进行直接I/O操作
dd if=/dev/zero of=testfile bs=1M count=1024 oflag=dsync

(3)异步I/O与缓存

异步I/O可以与缓存策略协同使用,从而提升应用程序的响应性以及磁盘I/O效率。

// 示例代码:结合异步I/O和缓存策略
#include <stdio.h>
#include <stdlib.h>
#include <aio.h>

int main() {
    struct aiocb aiocb;
    // 初始化异步I/O控制块,并设置异步操作标志...
    // 执行异步I/O操作...
    aio_read(&aiocb);
    // 处理其他任务,操作系统会在后台处理I/O操作...
    // 等待异步操作完成...
    aio_wait(&aiocb);
    return 0;
}

通过合理配置磁盘缓存和I/O缓存策略,能够显著提升Linux系统的磁盘I/O性能,特别是在高负载以及频繁访问数据的场景中。管理员需要依据具体的应用需求和系统负载,对缓存策略进行调整和优化。

七、磁盘阵列与RAID技术

磁盘阵列技术通过将多个物理磁盘组合成为一个逻辑单元,以此提升存储系统的性能和可靠性。RAID(Redundant Array of Independent Disks)是一种常见的磁盘阵列实现方式,它借助不同的数据分布和冗余策略,来提升磁盘I/O性能以及数据安全性。

7.1 RAID级别

RAID存在多种级别,每一种级别都具备其特定的性能和冗余特性。以下是一些常见的RAID级别:

(1)RAID 0

通过数据条带化(striping)来提升读写速度,但不提供数据冗余。它适用于对存储速度要求较高,然而对数据安全性要求不高的场景。

#创建RAID 0设备(需要mdadm工具)
mdadm --create /dev/md0 --level=0 --raid-devices=2 /dev/sda /dev/sdb

(2)RAID 1

通过镜像(mirroring)来实现数据冗余,提高了数据的可靠性,不过空间利用率仅为50%。它适用于对数据安全性要求较高的场景。

# 创建RAID 1设备
mdadm --create /dev/md1 --level=1 --raid-devices=2 /dev/sda /dev/sdb

(3)RAID 5

结合了条带化和分布式奇偶校验,既实现了性能提升,又具备数据冗余。它适用于需要平衡性能和冗余的场景。

# 创建RAID 5设备
mdadm --create /dev/md5 --level=5 --raid-devices=3 /dev/sda /dev/sdb /dev/sdc

(4)RAID 10

RAID 10是RAID 1和RAID 0的组合,兼具高性能和数据冗余。它适用于对性能和数据安全性都有较高要求的场景。

# 创建RAID 10设备
mdadm --create /dev/md10 --level=10 --raid-devices=4 /dev/sda /dev/sdb /dev/sdc /dev/sdd

7.2 管理RAID设备

使用mdadm工具能够对RAID设备进行管理,涵盖创建、监控以及修复RAID阵列等操作。

# 查看RAID设备状态
cat /proc/mdstat

# 修复RAID设备(如果某个磁盘出现问题)
mdadm --manage /dev/md0 --rebuild-map

7.3 监控RAID性能

对RAID性能进行监控,对于保障存储系统的高效运行意义重大。可以运用iostatmdstat以及其他工具来监控RAID设备的性能。

# 使用iostat监控RAID设备性能
iostat -dxm /dev/md0 1

7.4 RAID与磁盘I/O性能

RAID技术能够显著提升磁盘I/O性能,尤其是在读写操作方面。选择恰当的RAID级别和配置,对于最大化性能至关重要。同时,合理的RAID配置还能够增强数据的可靠性和容错能力。

通过运用磁盘阵列和RAID技术,系统管理员能够提升Linux系统的磁盘I/O性能,同时确保数据的安全性和可靠性。在选择RAID级别时,需要综合考量性能需求、数据冗余要求以及成本等多方面因素。

总结

综上所述,磁盘I/O在计算机运行中起着极为关键的作用。我们深入了解了磁盘I/O的概念,包括机械磁盘和固态磁盘的特性及工作原理。剖析了Linux存储系统I/O栈的层次结构与工作机制,明确了磁盘I/O的性能指标如吞吐量、IOPS和响应时间等。探讨了影响磁盘I/O性能的硬件设备、文件系统、系统配置和应用程序I/O模式等因素,并介绍了iostat、iotop、dd、fio等性能评估工具。还阐述了磁盘缓存与I/O缓存策略以及磁盘阵列和RAID技术对提升磁盘I/O性能的重要作用。这些知识为优化磁盘I/O性能、构建高效稳定的计算机存储系统提供了坚实基础,无论是系统管理员进行系统配置,还是开发人员优化应用程序的I/O操作,都能从中获取关键指导。

原文阅读

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件举报,一经查实,本站将立刻删除。

文章由技术书栈整理,本文链接:https://study.disign.me/article/202511/8.disk-io.md

发布时间: 2025-03-12