目录
Part1 I/O引擎在压测中的作用
Part2 Fio支持的I/O引擎介绍
众所周知,Fio是一款功能强大、易于上手的磁盘性能测试/评估工具被广泛使用,目前最新版本的Fio支持多达40+种I/O引擎,在哪种场景下应该使用哪种I/O引擎是使用者在使用Fio测试过程中比较容易迷茫的一个问题。
I/O 引擎(Input/Output Engine)在 磁盘性能测试工具中扮演着核心角色。它负责管理数据的读写操作,以及如何与操作系统交互以执行这些操作。不同的 I/O 引擎有不同的特性和适用场景
Part1 I/O引擎在压测中的作用
-
数据传输管理:
- 负责数据的读写操作,包括从文件系统读取数据或将数据写入文件系统。
- 控制数据传输的方向和方式。
-
并发控制:
- 管理多个 I/O 请求的同时执行,通过调整 I/O 深度 (
iodepth
) 参数来控制并发水平。 - 处理 I/O 请求队列,决定哪些请求优先执行。
- 管理多个 I/O 请求的同时执行,通过调整 I/O 深度 (
-
异步操作支持:
- 支持异步 I/O 操作,允许应用程序继续执行其他任务而不等待 I/O 操作完成。
- 利用操作系统提供的异步 I/O 接口,如 AIO (Asynchronous I/O) 或者 NBD (Network Block Device)。
-
缓冲管理:
- 可以选择是否使用操作系统的缓存机制。
- 直接 I/O 模式可以绕过操作系统缓存,直接访问物理磁盘,避免缓存带来的性能失真。
-
错误处理:
- 处理 I/O 错误,并根据配置进行相应的错误恢复或报告。
-
性能优化:
- 根据特定的硬件和软件环境优化 I/O 操作,提高整体性能。
-
资源管理:
- 管理 I/O 操作所使用的系统资源,如内存、CPU 时间等。
Part2 Fio支持的I/O引擎介绍
下面将介绍Fio目前支持的全部I/O引擎,包含了每种I/O引擎的功能和适合是场景,供你在实际测试过程中进行参考和借鉴:
-sync - 同步I/O引擎。这是最传统的I/O方法,每个I/O操作都会等待完成后再继续执行下一个操作,使用后的是Basic read(2) or write(2) I/O。通常用于较旧的或低速的磁盘设备,适用于测试简单的同步 I/O 场景。
-psync:类似于 sync
,但是使用 POSIX 异步通知机制,使用基本的 pread(2)
或pwrite(2)
I/O 操作。这是在所有支持的操作系统上的默认设置,Windows系统不支持。
-vsync:使用 VFS (Virtual File System) 层的同步 I/O。使用基本的readv(2) 或者 writev(2) I/O操作。通过将相邻的I/ o操作合并到单个提交中来模拟队列。
-pvsync:使用基本的preadv(2) 或pwritev(2) I/O操作。
-pvsync2:使用基本的 preadv2(2) 或者 pwritev2(2) I/O操作。
-libaio:基于 Linux 内核的 AIO (Asynchronous I/O) 实现,支持真正的异步 I/O 操作,适用于高性能存储设备,通常用于测试 SSD 或高速硬盘。请注意,Linux可能只支持非缓冲I/O的排队行为(设置direct=1或buffers =0)。这个引擎定义了特定于引擎的选项。
-io_uring:快速Linux本地异步I/O。支持异步IO的直接和缓冲IO。这个引擎定义了特定于引擎的选项。
-io_uring_cmd:用于传递命令的快速Linux本机异步I/O。这个引擎定义了特定于引擎的选项。
-Posixaio:POSIX异步I/O使用aio_read(3)和aio_write(3)。
-solarisaio:Solaris原生异步I/O。
-windowsaio:Windows本机异步I/O。默认为Windows上的默认引擎。
-mmap:使用mmap(2)对文件进行内存映射,使用memcpy(3)将数据复制到/从内存中。
-splice:Splice(2)用于传输数据,vmsplice(2)用于将数据从用户空间传输到内核。
-sg:SCSI generic sgv3 I/O。可以使用SG_IO ioctl进行同步,或者如果目标是sg字符设备,使用read(2)和write(2)进行异步I/O。需要文件名选项来指定块或字符设备。该引擎支持修剪操作。包括特定于引擎的选项。
-libzbc:使用libzbc库对分区块设备进行读、写、修剪和ZBC/ZAC操作。目标可以是SG字符设备,也可以是块设备文件。
-null:不传输任何数据,只是假装。这主要用于执行fio本身以及用于调试/测试目的。
-net:通过网络传输到给定的主机:端口。根据所使用的协议,主机名、端口、监听和文件名选项用于指定要建立哪种类型的连接,而协议选项决定将使用哪种协议。这个引擎定义了特定于引擎的选项。
-netsplice:与net引擎类似,但使用splice(2)和vmsplice(2)来映射数据和发送/接收。这个引擎定义了特定于引擎的选项。
-cpuio:不传输任何数据,但根据cpuload, cpuchunks和cpumode选项燃烧CPU周期。设置cpuload=85将导致该作业什么也不做,只会消耗85%的CPU。在SMP机器的情况下,使用numjobs=<nr_of_cpu>来获得所需的CPU使用率,因为cpuload只以所需的速率加载单个CPU。除非存在至少一个非cpu作业,否则作业永远不会结束。设置cpumode=qsort将默认的noop指令循环替换为qsort算法,以消耗更多的能量。
-rdma:RDMA I/O引擎支持InfiniBand、RoCE和iWARP协议的RDMA内存语义(RDMA_WRITE/RDMA_READ)和通道语义(Send/Recv)。这个引擎定义了特定于引擎的选项。
-falloc:I/O引擎进行常规故障以模拟数据传输为io引擎。
-ftruncate:发送ftruncate(2)操作以响应write (DDIR_WRITE)事件的I/O引擎。发出的每个ftruncate都将文件的大小设置为当前块偏移量。块大小被忽略。
-e4defrag:执行常规EXT4_IOC_MOVE_EXT ioctls来模拟请求DDIR_WRITE事件中的碎片整理活动的I/O引擎
-rados:I/O引擎支持通过librados直接访问Ceph可靠自主分布式对象存储(RADOS)。这个ioengine定义了引擎特定的选项。
-rbd:I/O引擎支持通过librbd直接访问Ceph Rados Block Devices (RBD),而不需要使用内核RBD驱动程序。这个ioengine定义了引擎特定的选项。
-http:I/O引擎支持使用libcurl通过HTTP(S)到WebDAV或S3端点的GET/PUT请求。此引擎只支持iodepth=1的直接IO;你需要通过numjobs来扩展它。可以使用Blocksize定义要创建的对象的大小。这个ioengine定义了引擎特定的选项。
-gfapi:使用GlusterFS libgfapi同步接口直接访问GlusterFS卷,而不必经过FUSE。这个ioengine定义了引擎特定的选项。
-gfapi_async:使用GlusterFS libgfapi异步接口直接访问GlusterFS卷,而不必经过FUSE。这个ioengine定义了引擎特定的选项。
-libhdfs:通过HDFS进行读写。filename选项用于指定要连接的hdfs name-node的主机、端口。这个引擎对偏移量的解释略有不同。在HDFS中,文件一旦创建就不能被修改,因此不可能随机写入。为了模拟这一点,libhdfs引擎期望在HDFS上创建一堆小文件,并根据fio后端生成的偏移量随机从中选择一个文件(参见示例作业文件创建此类文件,使用rw=write选项)。请注意,可能需要设置环境变量才能正确使用HDFS/libhdfs。每个作业使用自己到HDFS的连接。
-mtd:读取、写入和擦除MTD字符设备(例如,/dev/mtd0)。弃牌被视为擦除。根据底层设备类型,I/O可能必须以某种模式运行,例如,在NAND上,顺序写入以擦除块并在覆盖之前丢弃。trimwrite模式适用于此约束。
-dev-dax:使用设备DAX通过PMDK libpmem库对持久内存设备(例如,/dev/dax0.0)进行读写。
-external: 前缀指定加载外部I/O引擎对象文件。附加引擎文件名,例如ioengine=external:/tmp/foo。O加载引擎foo。/tmp目录下的0。路径可以是绝对的也可以是相对的。有关编写外部I/O引擎的详细信息,请参阅engines/skeleton_external.c。
-filecreate:只需创建文件,不对它们进行I/O操作。您仍然需要设置文件大小,这样所有的记帐仍然会发生,但是除了创建文件之外,不会执行实际的I/O。
-filestat:只需执行stat(),不对文件进行I/O操作。你需要设置' filesize '和' nrfiles ',这样文件才会被创建。该引擎用于测量文件查找和元数据访问。
-filedelete:只需通过unlink()删除这些文件,并且不对它们进行I/O操作。你需要设置' filesize '和' nrfiles ',这样文件就会被创建。该引擎用于检测文件删除。
-libpmem:通过PMDK libpmem库,使用mmap I/O对在持久内存设备上使用DAX挂载的文件系统上的文件进行读写。
-ime_psync:使用DDN的无限内存引擎(IME)进行同步读写。这个引擎是非常基本的,每当IO排队时都会发出对IME的调用。
-ime_psyncv:使用DDN的无限内存引擎(IME)进行同步读写。该引擎使用IME,并在发出对IME的调用之前尝试堆栈尽可能多的IO(如果IO是“连续的”并且IO深度未超过)。
-ime_aio:异步读写使用DDN的无限内存引擎(IME)。这个引擎将尝试通过创建IME请求来堆叠尽可能多的IOs。然后,FIO将决定何时提交这些请求。
-libiscsi:使用libiscsi对iscsi lun进行读写操作。
-nbd:对NBD (Network Block Device)进行读写。
-libcufile:I/O引擎支持libcufile同步访问nvidia-fs和支持GPUDirect storage的文件系统。该引擎执行I/O时不会在用户空间和内核之间传输缓冲区,除非设置了verify或cuda_io为posix。我不应该是cudamalloc。这个ioengine定义了引擎特定的选项。
-dfs:支持通过libdfs对DAOS文件系统(DFS)进行异步读写操作的I/O引擎。
-nfs:I/O引擎支持从用户空间通过libnfs对NFS文件系统进行异步读写操作。这对于实现比通过内核NFS可能实现的更高的并发性和吞吐量非常有用。
-exec:执行第三方工具。可用于在作业运行时期间执行监视。
-xnvme:I/O引擎使用xNVMe C API,用于NVMe设备。NVMe引擎提供了通过libio, IOCTLs, io_uring, SPDK NVMe驱动程序或您自己的自定义NVMe驱动程序访问GNU/Linux内核NVMe驱动程序的灵活性。xnvme引擎包含特定于引擎的选项。
-libblkio:使用libblkio库(/libblkio/libblkio)。要使用的特定驱动程序必须使用libblkio_driver来设置。如果没有指定mem/iomem,内存分配将委托给libblkio(因此保证与选定的驱动程序一起工作)。每个进程使用一个libblkio实例,因此所有作业设置选项线程将共享一个实例(每个线程一个队列),并且必须指定兼容的选项。请注意,一些驱动程序不允许多个实例同时访问同一个设备或文件,但允许线程访问。
注意:每种I/O引擎都有其适用场景和技术特点,选择正确的引擎对于准确评估系统的I/O性能至关重要。例如,如果您正在测试基于NVMe的SSD,那么使用`xnvme`引擎可能更为合适;而如果您想要模拟网络文件系统的负载,则可以考虑使用`nfs`引擎。在运行fio测试时,可以通过`-ioengine`选项来指定使用的I/O引擎,同时如果场景与你指定的I/O引擎不一致,可能引发fio抛出一个ioengine错误。