![Linux 缓冲区缓存对 IO 写入有影响吗?](https://linux22.com/image/540420/Linux%20%E7%BC%93%E5%86%B2%E5%8C%BA%E7%BC%93%E5%AD%98%E5%AF%B9%20IO%20%E5%86%99%E5%85%A5%E6%9C%89%E5%BD%B1%E5%93%8D%E5%90%97%EF%BC%9F.png)
我在 Linux 服务器(内核 2.6.37、16 核、32G RAM)上的两个文件系统之间复制大型文件(3 x 30G),但性能不佳。我怀疑缓冲区缓存的使用正在影响 I/O 性能。
为了尝试缩小问题范围,我直接在 SAS 磁盘上使用 fio 来监控性能。
以下是 2 次 fio 运行的输出(第一次 direct=1,第二次 direct=0):
配置:
[test]
rw=write
blocksize=32k
size=20G
filename=/dev/sda
# direct=1
运行 1:
test: (g=0): rw=write, bs=32K-32K/32K-32K, ioengine=sync, iodepth=1
Starting 1 process
Jobs: 1 (f=1): [W] [100.0% done] [0K/205M /s] [0/6K iops] [eta 00m:00s]
test: (groupid=0, jobs=1): err= 0: pid=4667
write: io=20,480MB, bw=199MB/s, iops=6,381, runt=102698msec
clat (usec): min=104, max=13,388, avg=152.06, stdev=72.43
bw (KB/s) : min=192448, max=213824, per=100.01%, avg=204232.82, stdev=4084.67
cpu : usr=3.37%, sys=16.55%, ctx=655410, majf=0, minf=29
IO depths : 1=100.0%, 2=0.0%, 4=0.0%, 8=0.0%, 16=0.0%, 32=0.0%, >=64=0.0%
submit : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
complete : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
issued r/w: total=0/655360, short=0/0
lat (usec): 250=99.50%, 500=0.45%, 750=0.01%, 1000=0.01%
lat (msec): 2=0.01%, 4=0.02%, 10=0.01%, 20=0.01%
Run status group 0 (all jobs):
WRITE: io=20,480MB, aggrb=199MB/s, minb=204MB/s, maxb=204MB/s, mint=102698msec, maxt=102698msec
Disk stats (read/write):
sda: ios=0/655238, merge=0/0, ticks=0/79552, in_queue=78640, util=76.55%
运行 2:
test: (g=0): rw=write, bs=32K-32K/32K-32K, ioengine=sync, iodepth=1
Starting 1 process
Jobs: 1 (f=1): [W] [100.0% done] [0K/0K /s] [0/0 iops] [eta 00m:00s]
test: (groupid=0, jobs=1): err= 0: pid=4733
write: io=20,480MB, bw=91,265KB/s, iops=2,852, runt=229786msec
clat (usec): min=16, max=127K, avg=349.53, stdev=4694.98
bw (KB/s) : min=56013, max=1390016, per=101.47%, avg=92607.31, stdev=167453.17
cpu : usr=0.41%, sys=6.93%, ctx=21128, majf=0, minf=33
IO depths : 1=100.0%, 2=0.0%, 4=0.0%, 8=0.0%, 16=0.0%, 32=0.0%, >=64=0.0%
submit : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
complete : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
issued r/w: total=0/655360, short=0/0
lat (usec): 20=5.53%, 50=93.89%, 100=0.02%, 250=0.01%, 500=0.01%
lat (msec): 2=0.01%, 4=0.01%, 10=0.01%, 20=0.01%, 50=0.12%
lat (msec): 100=0.38%, 250=0.04%
Run status group 0 (all jobs):
WRITE: io=20,480MB, aggrb=91,265KB/s, minb=93,455KB/s, maxb=93,455KB/s, mint=229786msec, maxt=229786msec
Disk stats (read/write):
sda: ios=8/79811, merge=7/7721388, ticks=9/32418456, in_queue=32471983, util=98.98%
我对 fio 的了解不够,无法解释结果,但我不认为使用缓冲区缓存的整体性能比 O_DIRECT 低 50%。
有人能帮我解释一下 fio 的输出吗?
有没有什么内核调整可以修复或最小化这个问题?
多谢,
答案1
使用 O_DIRECT,内核会绕过所有常用的缓存机制,直接写入磁盘。由于您不使用 O_SYNC,如果启用了缓存(不使用 O_DIRECT),那么内核可能会骗您说“是的,是的,我已经写入了,不用担心!”,即使它没有将其写入磁盘,也只是将其写入了一些缓存(磁盘缓存/页面缓存/...)。
答案2
直接执行确实意味着您不需要花时间进行复制,因此直接 I/O 的速度更快并非不可能,但结果看起来很奇怪,第二次运行的完成时间比第一次运行的完成时间要大得多。同时比较磁盘统计数据:
sda: ios=0/655238, merge=0/0, ticks=0/79552, in_queue=78640, util=76.55%
对比
sda: ios=8/79811, merge=7/7721388, ticks=9/32418456, in_queue=32471983, util=98.98%
第一次运行没有进行任何 I/O 合并(merge=),而第二次运行进行了。在第一次运行期间,磁盘并非完全繁忙(util=),而在第二次运行中,磁盘非常繁忙。in_queue
第二次运行的时间也更长,表明 I/O 在内核中备份。奇怪 - 也许写回不知何故中断了?您可以通过将 I/O 调度程序更改为noop
或来解决该问题,deadline
但它确实看起来有问题...