在对 Linux (2.6.18) 中的文件随机读取 I/O 进行基准测试时,我注意到了一个奇怪的问题。基准测试程序是我自己编写的程序,它只是不断地从随机偏移量读取 16KB 的文件。
我通过 systemtap 跟踪了系统调用级别和 scsi 级别的 I/O 行为,并注意到一个 16KB sysread 发出了 2 个 scsi I/O,如下所示。
SYSPREAD random(8472) 3, 0x16fc5200, 16384, 128137183232
SCSI random(8472) 0 1 0 0 start-sector: 226321183 size: 4096 bufflen 4096 FROM_DEVICE 1354354008068009
SCSI random(8472) 0 1 0 0 start-sector: 226323431 size: 16384 bufflen 16384 FROM_DEVICE 1354354008075927
SYSPREAD random(8472) 3, 0x16fc5200, 16384, 21807710208
SCSI random(8472) 0 1 0 0 start-sector: 1889888935 size: 4096 bufflen 4096 FROM_DEVICE 1354354008085128
SCSI random(8472) 0 1 0 0 start-sector: 1889891823 size: 16384 bufflen 16384 FROM_DEVICE 1354354008097161
SYSPREAD random(8472) 3, 0x16fc5200, 16384, 139365318656
SCSI random(8472) 0 1 0 0 start-sector: 254092663 size: 4096 bufflen 4096 FROM_DEVICE 1354354008100633
SCSI random(8472) 0 1 0 0 start-sector: 254094879 size: 16384 bufflen 16384 FROM_DEVICE 1354354008111723
SYSPREAD random(8472) 3, 0x16fc5200, 16384, 60304424960
SCSI random(8472) 0 1 0 0 start-sector: 58119807 size: 4096 bufflen 4096 FROM_DEVICE 1354354008120469
SCSI random(8472) 0 1 0 0 start-sector: 58125415 size: 16384 bufflen 16384 FROM_DEVICE 1354354008126343
如上所示,一个 16KB 预读发出 2 个 scsi I/O。(我使用探针 scsi.iodispatching 跟踪了 scsi io 调度。请忽略除起始扇区和大小之外的值。)
一个 scsi I/O 是应用程序请求的 16KB I/O,没问题。问题是另一个 4KB I/O,我不知道为什么 Linux 会发出该 I/O。
当然,奇怪的 4KB I/O 会降低 I/O 性能,我遇到了麻烦。我也使用 fio(著名的 I/O 基准测试工具)并注意到了同样的问题,所以这不是应用程序的问题。
有人能向我解释一下吗?
答案1
这可能是一个您已经检查过的愚蠢/显而易见的事情,但是您的文件系统是否已使用该noatime
标志安装?
如果你没有指定,noatime
那么 Linux 需要在每次访问文件时更新 inode(以设置A访问时间),这意味着它必须读取包含 inode 的磁盘区域,然后将其写回。(顺便说一句,这就是为什么性能至关重要的读取密集型文件系统应该使用noatime
- 不断更新 inode 的 I/O 是巨大的,并且可能会对性能造成明显的影响)。
答案2
我知道发生了什么事,但我不知道它是做什么用的。
Ext3 文件系统每 4096KB(8192 个扇区)数据中都有一些 4KB 数据。从视觉上看,数据排列如下。
|4KB|4096KB|4KB|4096KB|4KB|4096KB| ...
而4096KB区域是只供应用程序访问的,当第一次访问第一个4096KB区域时,OS会先读取4096KB区域之前的4KB,然后再读取4096KB区域中需要的数据。
当随机访问大型文件(与 DRAM 大小相比)时,每个 I/O 都很少有机会击中页面缓存,因此每个 I/O 请求都伴随着 4KB I/O。
问题是 4KB 数据是做什么用的?这个位置是文件系统的元数据吗?有什么办法可以删除它吗?或者有什么办法可以只清除 4096KB 区域?
欢迎提出任何意见和建议。
(我在许多具有多个内核版本的机器上进行了测试。所有机器都会发生这种情况。)
谢谢。
答案3
我搞明白了。它来自 ext3 间接块映射。(Ext3 有一个块,其中每 1024 个块都有一个块指针。)
我将文件系统更改为 ext4 后问题就消失了。(Ext4 具有更高效的块寻址方案。)
谢谢你们。