「Linux」- 磁盘 IO

  CREATED BY JENKINSBOT

按 存储介质 分类:机械磁盘、固态硬盘

磁盘是可以持久化存储的设备,根据存储介质的不同,常见磁盘可以分为两类:机械磁盘和固态磁盘:

机械磁盘(Hard Disk Driver),HDD

在读写数据前,需要移动读写磁头,定位到数据所在的磁道,然后才能访问数据。

如果 I/O 请求刚好连续,那就不需要磁道寻址,自然可以获得最佳性能。这其实就是我们熟悉的,连续 I/O 的工作原理

随机 I/O,它需要不停地移动磁头,来定位数据位置,所以读写速度就会比较慢。

固态硬盘(Solid State Disk),SSD

固态磁盘不需要磁道寻址,所以,不管是连续 I/O,还是随机 I/O 的性能,都比机械磁盘要好得多。

随机 I/O vs. 连续 I/O

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

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

2)对固态磁盘来说,虽然随机性能优于 HDD,但同样存在“先擦除再写入”的限制(需要了解 SSD 原理)。随机读写会导致大量的垃圾回收,所以相对应的随机 I/O 的性能弱于连续 I/O

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

磁盘的最小读写单位

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

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

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

按 接口类型 分类:IDE、SCSI、SAS、SATA、FC

按照接口来分类,比如可以把硬盘分为
1)IDE(Integrated Drive Electronics),在系统中磁盘前缀 hd
2)SCSI(Small Computer System Interface),在系统中磁盘前缀 sd
3)SAS(Serial Attached SCSI)
4)SATA(Serial ATA)
5)FC(Fibre Channel)

按 使用方式 分类:RAID

RAID(Redundant Array of Independent Disks)

把多块磁盘组合成一个逻辑磁盘,构成冗余独立磁盘阵列,从而可以提高数据访问的性能,并且增强数据存储的可靠性。

RAID 一般可以划分为多个级别,如 RAID0、RAID1、RAID5、RAID10 等:
1)RAID0 有最优的读写性能,但不提供数据冗余的功能
2)其他级别的 RAID,在提供数据冗余的基础上,对读写性能也有一定程度的优化

按 存储架构 分类:NFS、SMB、iSCSI

这些磁盘组合成一个网络存储集群,再通过 NFS、SMB、iSCSI 等网络存储协议,暴露给服务器使用。

主设备号 与 次设备号

在 Linux 中,磁盘实际上是作为一个块设备来管理的,也就是以块为单位读写数据,并且支持随机读写。

每个块设备都会被赋予两个设备号,分别是主、次设备号:
1)主设备号,用在驱动程序中,用来区分设备类型;
2)次设备号,用来给多个同类设备编号;

通用块层

为了减小不同块设备的差异带来的影响,Linux 通过统一的通用块层来管理各种不同的块设备,其思想与 VFS 类似;

通用块层,其实是处在文件系统磁盘驱动中间的一个块设备抽象层:
1)向上,为文件系统和应用程序,提供访问块设备的标准接口;
2)向下,把各种异构的磁盘设备抽象为统一的块设备,并提供统一框架来管理这些设备的驱动程序;
3)通用块层还会给文件系统和应用程序发来的 I/O 请求排队,并通过重新排序、请求合并等方式,提高磁盘读写的效率;

四种 I/O 调度算法

对 I/O 请求排序的过程,也就是我们熟悉的 I/O 调度,Linux 内核支持四种 I/O 调度算法:

NONE

并不能算 I/O 调度算法。因为它完全不使用任何 I/O 调度器,对文件系统和应用程序的 I/O 其实不做任何处理,常用在虚拟机中(此时磁盘 I/O 调度完全由物理机负责)。

NOOP

最简单的一种 I/O 调度算法。它实际上是一个先入先出的队列,只做一些最基本的请求合并,常用于 SSD 磁盘。

CFQ,(Completely Fair Scheduler)

也被称为完全公平调度器,是现在很多发行版的默认 I/O 调度器,它为每个进程维护了一个 I/O 调度队列,并按照时间片来均匀分布每个进程的 I/O 请求。类似于进程 CPU 调度,CFQ 还支持进程 I/O 的优先级调度,所以它适用于运行大量进程的系统,像是桌面环境、多媒体应用等。

DeadLine

分别为读、写请求创建了不同的 I/O 队列,可以提高机械磁盘的吞吐量,并确保达到最终期限(deadline)的请求被优先处理。DeadLine 调度算法,多用在 I/O 压力比较重的场景,比如数据库等。