需要对Linux上的固态进行一个读写测试,我知道是可以 dd 方式直接测试的,但是 dd 只能顺序读写,无法随机读写,因此这里再提供另一种方法。

在 Linux 上使用 dd 工具可以直接测试硬盘的读写速度

使用 dd 测试读写速度

写入测试

可以使用 dd 命令生成一个测试文件来测量写入速度。例如,使用 1M 的块大小生成一个 1GB 的测试文件:

dd if=/dev/zero of=/path/to/your/testfile bs=1M count=1024 oflag=direct

这个命令解释如下:

  • if=/dev/zero:从 /dev/zero 读取数据(生成零字节数据)。
  • of=/path/to/your/testfile:输出到指定的测试文件。
  • bs=1M:块大小为 1MB。
  • count=1024:写入 1024 个块,总计 1GB。
  • oflag=direct:使用直接 I/O,不经过操作系统缓存。

读取测试

可以使用 dd 命令从生成的测试文件中读取数据来测量读取速度:

dd if=/path/to/your/testfile of=/dev/null bs=1M count=1024 iflag=direct

这个命令解释如下:

  • if=/path/to/your/testfile:从指定的测试文件中读取数据。
  • of=/dev/null:将数据丢弃。
  • bs=1M:块大小为 1MB。
  • count=1024:读取 1024 个块,总计 1GB。
  • iflag=direct:使用直接 I/O,不经过操作系统缓存。

在文件 I/O 操作中,直接 I/O 和缓存 I/O 是两种不同的操作模式。

缓存 I/O(Buffered I/O)

默认情况下,操作系统在进行文件读写时会使用缓存 I/O,即通过系统的页缓存(page cache)来缓冲数据。这种方式的优点是可以提高文件操作的速度,因为许多读写操作实际上是在内存中进行的,减少了与磁盘的直接交互次数。但也有一些缺点:

  • 读写操作可能被系统缓存所影响,导致实际磁盘性能的测量不准确。
  • 大量数据的缓存操作会消耗系统内存,可能导致其他应用程序的内存不足。

直接 I/O(Direct I/O)

直接 I/O 是绕过操作系统缓存,直接从磁盘进行读写操作的一种模式。在 Linux 上,可以通过 O_DIRECT 标志来实现直接 I/O。使用直接 I/O 有以下优点和缺点:

优点

  1. 准确的性能测量:绕过操作系统缓存,直接与磁盘进行读写操作,可以更准确地反映磁盘的实际性能。
  2. 减少内存使用:不使用系统缓存,减少了内存消耗,对内存资源紧张的系统有益。
  3. 适合某些应用场景:例如数据库系统,直接 I/O 可以提供更稳定的性能,因为这些应用通常有自己的缓存机制,不需要操作系统的缓存。

缺点

  1. 较高的延迟:每次读写操作都直接访问磁盘,可能会导致较高的延迟,尤其是在小块数据的随机读写操作中。
  2. 复杂的内存对齐要求:直接 I/O 通常要求缓冲区和文件偏移都对齐到文件系统块的大小,增加了编程复杂性。

iflag=direct 的作用

dd 命令中使用 iflag=direct(输入标志)或 oflag=direct(输出标志)选项,可以启用直接 I/O 模式。例如:

dd if=/path/to/your/testfile of=/dev/null bs=1M iflag=direct

上述命令表示:

  • if=/path/to/your/testfile:从指定的文件中读取数据。
  • of=/dev/null:将数据丢弃。
  • bs=1M:块大小为 1MB。
  • iflag=direct:使用直接 I/O 模式进行读取操作。

在这个模式下,数据读写操作不会使用系统缓存,而是直接从磁盘进行读写。这有助于更准确地测量硬盘的实际读写性能。

dd 的优缺点

优点

  1. 简单易用dd 命令简单直接,易于记忆和使用。
  2. 无需额外安装dd 是大多数 Linux 发行版的默认工具,通常不需要额外安装。

缺点

  1. 缺乏灵活性dd 不支持复杂的 I/O 模式和参数调整,不能模拟多线程、多进程等高级 I/O 测试场景。
  2. 报告信息有限dd 提供的测试结果信息有限,主要是简单的速度统计,缺乏详细的性能分析数据,如 IOPS、延迟等。
  3. 无法进行随机 I/O 测试dd 主要用于顺序读写测试,不适合进行随机读写性能测试。

fio 是一个强大的 I/O 性能测试工具,支持多种 I/O 引擎和参数配置,非常适合用于性能测试和分析。

安装 fio

使用包管理工具进行安装:

对于基于 Debian 的系统 (如 Ubuntu):

sudo apt-get install fio

对于基于 Red Hat 的系统 (如 CentOS):

sudo yum install fio

使用 fio 测试 4K 读写速度

安装完成后,可以使用以下命令来测试 4K 随机读写速度:

4K 随机读取测试

创建一个 read.fio 文件,内容如下:

[global]
name=randread
ioengine=libaio
iodepth=1
rw=randread
bs=4k
direct=1
size=1G
numjobs=1
runtime=60
group_reporting

[randread]
filename=/path/to/your/testfile

执行测试命令:

fio read.fio

4K 随机写入测试

创建一个 write.fio 文件,内容如下:

[global]
name=randwrite
ioengine=libaio
iodepth=1
rw=randwrite
bs=4k
direct=1
size=1G
numjobs=1
runtime=60
group_reporting

[randwrite]
filename=/path/to/your/testfile

执行测试命令:

fio write.fio

解释测试参数

  • ioengine=libaio:使用异步 I/O 引擎。
  • iodepth=1:I/O 队列深度为 1。
  • rw=randreadrw=randwrite:分别表示随机读取和随机写入。
  • bs=4k:块大小为 4KB。
  • direct=1:使用直接 I/O,不经过操作系统缓存。
  • size=1G:测试文件的大小为 1GB。
  • numjobs=1:并发作业数为 1。
  • runtime=60:测试运行时间为 60 秒。
  • group_reporting:汇总报告结果。

结果分析

测试结果将会显示 IOPS(每秒输入输出操作数)和吞吐量(MB/s),以及延迟等信息。4K 随机读写速度通常用于衡量硬盘在处理小文件时的性能,这是固态硬盘性能的重要指标之一。一般来说,4K 随机读写性能越高,固态硬盘在日常使用中的表现也就越好。

修改 fio 配置文件以测试 1M 读写速度

要测试 1M 读写速度,只需要修改 fio 配置文件中的块大小参数 bs 为 1M。

1M 随机读取测试

创建或修改 read_1M.fio 文件,内容如下:

[global]
name=randread
ioengine=libaio
iodepth=1
rw=randread
bs=1M
direct=1
size=1G
numjobs=1
runtime=60
group_reporting

[randread]
filename=/path/to/your/testfile

执行测试命令:

fio read_1M.fio

1M 随机写入测试

创建或修改 write_1M.fio 文件,内容如下:

[global]
name=randwrite
ioengine=libaio
iodepth=1
rw=randwrite
bs=1M
direct=1
size=1G
numjobs=1
runtime=60
group_reporting

[randwrite]
filename=/path/to/your/testfile

执行测试命令:

fio write_1M.fio

fio 的特点

  1. 灵活性高fio 支持多种 I/O 模式和参数调整,可以模拟复杂的 I/O 场景,如随机读写、多线程、多进程等。
  2. 详细报告fio 提供详细的性能分析报告,包括 IOPS、延迟、带宽等多种性能指标。
  3. 适用范围广fio 可以测试多种存储设备和文件系统,适用于更广泛的性能测试需求。

为什么 4K 读写特别慢?

4K 随机读写速度通常比大块读写速度慢,原因如下:

  1. 数据块大小: 4K 是一个相对较小的数据块,每次操作处理的数据量小,导致需要更多的 I/O 操作来完成同样的数据传输量。这增加了 IOPS(每秒输入输出操作数)的负担。

  2. 寻址开销: 小数据块的随机读写会导致磁盘进行频繁的寻址操作,增加了寻道时间和延迟。在机械硬盘(HDD)中,这个问题更为显著,但在固态硬盘(SSD)中,虽然没有机械臂移动,内部的地址映射和控制器处理也会增加延迟。

  3. 文件系统和控制器效率: 文件系统和硬盘控制器在处理小数据块时,效率可能会降低。SSD 的控制器通常为大块数据优化,小块数据的处理会增加控制器的工作负担,导致性能下降。

  4. 缓存和写入放大: 现代 SSD 通常有缓存机制,大块数据的顺序读写更容易利用缓存优化性能。而小块数据的随机读写会导致缓存命中率低,无法充分利用缓存优势。此外,小块数据写入会导致 SSD 内部的写入放大效应,增加额外的写入操作量,进一步降低性能。

通过测试 1M 数据块的读写速度,可以更好地了解 SSD 在处理大块数据时的性能表现。这种测试通常显示更高的吞吐量和较低的延迟,因为大块数据传输减少了I/O 操作数,提高了整体效率。

使用 fio 进行多线程读写测试

fio 支持多线程读写测试,这可以用来模拟实际应用场景中的并发 I/O 操作,测试磁盘在高并发情况下的性能表现。下面是一个多线程读写测试的配置示例:

多线程随机读取测试

创建一个 randread_multi.fio 文件,内容如下:

[global]
name=randread
ioengine=libaio
iodepth=32
rw=randread
bs=4k
direct=1
size=1G
numjobs=4
runtime=60
group_reporting

[randread]
filename=/path/to/your/testfile

执行测试命令:

fio randread_multi.fio

多线程随机写入测试

创建一个 randwrite_multi.fio 文件,内容如下:

[global]
name=randwrite
ioengine=libaio
iodepth=32
rw=randwrite
bs=4k
direct=1
size=1G
numjobs=4
runtime=60
group_reporting

[randwrite]
filename=/path/to/your/testfile

执行测试命令:

fio randwrite_multi.fio

配置参数解释

  • ioengine=libaio:使用异步 I/O 引擎。
  • iodepth=32:I/O 队列深度为 32。
  • rw=randreadrw=randwrite:分别表示随机读取和随机写入。
  • bs=4k:块大小为 4KB。
  • direct=1:使用直接 I/O,不经过操作系统缓存。
  • size=1G:测试文件的大小为 1GB。
  • numjobs=4:并发作业数为 4,表示有 4 个线程同时进行 I/O 操作。
  • runtime=60:测试运行时间为 60 秒。
  • group_reporting:汇总报告结果。

多线程读写测试的性能评估

多线程读写测试可以帮助评估以下性能指标:

  1. IOPS (每秒输入输出操作数):衡量存储设备在多线程并发情况下的处理能力。
  2. 带宽 (MB/s):评估存储设备在并发读写操作下的数据传输速度。
  3. 延迟 (Latency):分析并发 I/O 操作对读写延迟的影响,特别是高并发下的延迟分布。
  4. 资源利用率:评估存储设备在多线程环境中的资源利用效率,如 CPU 和内存占用。

dd 只能顺序读写的原因

dd 是一个简单的命令行工具,设计用于执行直接的数据复制操作。以下是 dd 只能进行顺序读写的原因:

  1. 命令设计初衷dd 的设计初衷是进行数据备份和恢复操作,主要用于顺序读写整个块设备或文件。
  2. 缺乏随机读写支持dd 命令本身没有内置的机制来实现随机读写操作。它按照指定的块大小和顺序读取或写入数据,无法像 fio 一样指定随机读写模式。
  3. 简单性和灵活性限制dd 的设计是为了简单直接地完成数据复制任务,因此缺乏 fio 那样的灵活性和复杂的 I/O 模式支持。