我正在尝试根据文件系统块大小进行一些测试,以确定由于 IO 不良而导致网格作业中的一些潜在瓶颈。我注意到作业期间有很多 8096 B 的小文件增量,而 FS 的块大小为:
stat -fc %s /my/filesytem
1048576
这远非最佳。为了模拟这种行为,我创建了两个 1GB 到 20GB 的小随机文件,并以 和dd
作为 /dev/urandom
源,我尝试了这个 python 代码:
#!/bin/python
bsize=8096
print('File random.20g1')
print(strftime("%Y-%m-%d_%H:%M:%S"))
f1= open('random.20g1','rb')
f2= open('random.20g1.dest','wb')
while True:
b = f1.read(bsize)
if b:
f2.write(b)
else:
break
print(strftime("%Y-%m-%d_%H:%M:%S"))
我也尝试过同样的操作bsize=1048576
。
我首先观察到 8096 和 1048576 的块大小之间存在 4 秒的小读/写时间差异(大块大小的读/写时间少 4 秒)。
第一个结果很有希望,但经过进一步测试,例如将文件大小增加到 20GB 或对 10 个 GB 文件执行相同的操作,我观察到性能方面始终有 4/3 秒的相同差异,并且增益永远不会缩放文件。
我在测试过程中做错了什么吗?或者您认为这没问题?
例如,我希望在增加文件大小方面有所改进。
答案1
此代码
while True:
b = f1.read(bsize)
if b:
f2.write(b)
else:
break
是在做顺序的读取和写入 - 给定任何bsize
,它读取第一个bsize
字节,将它们写入目标文件,然后读取第二个bsize
字节,将它们附加到目标文件,...
您的操作系统将通过以下方式缓冲这些内容页面缓存,甚至可以像评论中提到的 @StephenKitt 那样预读并预缓冲您的输入数据。因此,对实际磁盘的底层 IO 调用最终会合并成更大的块,可能是您提到的 1 MB。
您在性能中看到的微小差异几乎可以肯定是完全由于当您使用较小的bsize
进程时必须对内核进行更多的系统调用才能实际移动数据。
因此,几乎可以肯定,这就是为什么当您更改测试代码时您看不到太大差异的原因bsize
,但如果没有有关系统的更多详细信息,则实际上不可能确定。
更多的...
你所做的实际上与
dd if=random.20g1 of=random.20g1.dest bs=8192
如果你要实际使用dd
,你可以做更多的事情来测试磁盘IO(只需看看手册页- 例如,您可以使用直接 IO 绕过页面缓存),但最终,您可以执行的 IO 测试dd
非常有限,因为它将是连续的。 dd
将向您展示靠近您的最好的IO 性能,但它无法模拟大量现实世界的工作负载,从而揭示 IO 性能的缺点。
您需要确定有关网格作业实际使用的 IO 模式的更多信息 - 它是否像您的测试中那样进行顺序读取/写入,或者它是否正在执行随机的在执行 IO 之前,将其在文件中查找的位置读取和/或写入到有效的随机位置?随机 IO 操作对文件系统和底层磁盘硬件(尤其是旋转磁盘)的要求更高。可以每秒传输数百 MB 的流顺序 IO 的系统可能会被削弱到很少的千字节每秒随机小规模 IO 操作。特别是当您使用低速 5,000 RPM SATA 磁盘时。
当不了解文件系统和 RAID 阵列的人设置存储时,情况可能会变得非常糟糕。您提到的 1 MB 文件系统块大小肯定看起来您可能正在错误的“越大总是更快”的范例下处理存储系统设置。
将“越大总是越快”的范例与 RAID5/6 阵列和随机小块 IO(例如您的网格作业似乎正在做的事情)之类的东西混合在一起可能会导致极其糟糕的 IO 性能。
strace
你可以在Linux上使用获取您的工作进行的实际系统调用。查找诸如lseek
、write
、read
、 和pwrite
之类的调用pread
。这将告诉您您的工作执行的实际 IO 模式。
一旦获得 IO 模式,您就可以使用接近复制该模式的工具来测试和基准测试该模式下的实际存储性能。您可能需要一个可以向/从随机位置写入或读取的工具。再次假设Linux,你可以从fio
。您可能需要使用随机读/写选项。