一个16K随机读取I / O在Linux中发出2个scsi I / O(16K和4K)请求

当在Linux(2.6.18)中对文件的随机读I / O进行基准testing时,我注意到了奇怪的问题。 Benchmarking程序是我自己的程序,它只是从一个随机的偏移量中读取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 pread发出2个scsi I / O。 (我跟踪调查scsi.iodispatching scsi调度,请忽略除开始部门和大小的值。

一个scsi I / O是从应用程序请求的16KB I / O,并没有问题。 其他的4KB I / O,我不知道为什么Linux发出I / O。

当然,I / O性能会由于4KB的I / O而降低,我遇到了麻烦。 我也使用fio(着名的I / O基准工具),并注意到相同的问题,所以它不是从应用程序。

任何人都可以向我解释这个?

这可能是一个愚蠢/明显的事情,你已经检查,但是你的文件系统挂载noatime标志?

如果您没有指定noatime则Linux每次访问文件时都需要更新inode(设置连接时间 ),这意味着必须读取包含inode的磁盘区域,并将其写回。 (顺便说一句,这就是性能关键的读取密集型文件系统应该在noatime上安装的原因 – 用于更新inode的I / O不断变化很大,性能可以测量。

我想清楚发生了什么,但是我不知道是什么原因。

Ext3文件系统在每个4096KB(8192个扇区)数据中有一些4KB的数据。 在视觉上,数据如下所示alignment。

| 4KB | 4096KB | 4KB | 4096KB | 4KB | 4096KB | …

而4096KB的区域只能由应用程序访问。 当第一次访问第一个4096KB区域时,操作系统首先读取4096KB区域之前的4KB,然后在4096KB区域读取请求的数据。

当随机访问一个大文件(与DRAM大小相比)时,每个I / O都有很less的打击页面的机会,所以每个I / O请求都与4KB I / O一起。

东西是4KB的数据是什么? 这是文件系统的位置元数据吗? 有什么办法可以删除这个? 或者有什么办法可以清除4096KB的区域?

任何意见和build议,表示赞赏。

(我在很多机器上testing过许多内核版本,这种情况发生在所有的机器上)

谢谢。

我想到了。 这是从ext3间接块映射。 (Ext3有一个块,每1024个块有块指针。)

我将文件系统更改为ext4使问题消失。 (Ext4有更高效的块寻址scheme。)

谢谢你们。