我正在尝试根据文件系统块大小进行一些测试,以识别由于 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 秒的相同差异,并且增益永远不会扩展文件。
我在我的测试过程中做错了什么还是你觉得没问题?
例如,我本来希望在增加文件大小方面有所改进。
这段代码
正在执行顺序读取和写入 - 给定 any
bsize
,它读取第一个bsize
字节,将它们写入目标文件,然后读取第二bsize
个字节,将它们附加到目标文件,...您的操作系统将通过页面缓存缓冲这些内容,甚至可以像评论中提到的@StephenKitt 那样预读和预缓冲您的输入数据。因此,对实际磁盘的底层 IO 调用最终会合并成更大的块,可能是您提到的 1 MB。
您在性能上看到的微小差异几乎肯定是因为当您使用较小的进程时,
bsize
您的进程必须对内核进行更多的系统调用才能实际移动数据。因此,几乎可以肯定这就是为什么您在更改
bsize
测试代码时看不到太大差异的原因,但是如果没有关于您的系统的更多详细信息,就无法确定。更多的...
你正在做的实际上是相同的
如果您要实际使用
dd
,您可以做更多的事情来测试磁盘 IO(只需查看手册页- 例如,您可以使用直接 IO 绕过页面缓存),但最终,IO 测试您can do withdd
非常有限,因为它将是连续的。dd
将向您展示接近最佳IO 性能,但它无法模拟大量揭示 IO 性能缺点的真实工作负载。您需要确定有关网格作业实际使用的 IO 模式的更多信息 - 它是像在您的测试中那样执行顺序读取/写入,还是在文件中寻找有效随机的位置执行随机读取和/或写入做IO之前的位置?随机 IO 操作对文件系统和底层磁盘硬件的要求更高——尤其是旋转磁盘。可以移动数百 MB/秒的流式顺序 IO 的系统可能会被随机的小尺寸 IO 操作削弱到每秒几千字节。特别是如果您使用的是 SLOW 5,000-RPM SATA 磁盘。
当不了解文件系统和 RAID 阵列的人设置存储时,情况会变得非常糟糕。您提到的 1 MB 文件系统块大小肯定看起来您可能正在处理错误的“越大总是更快”范式下的存储系统设置。
将“越大越快”的范式与 RAID5/6 阵列和随机小块 IO(例如您的网格作业似乎正在做的事情)等东西混合在一起,可能会导致 IO 性能非常糟糕。
您可以
strace
在 Linux上使用来获取您的工作所做的实际系统调用。查找诸如lseek
、write
、read
和pwrite
的调用pread
。这将告诉您您的工作所做的实际 IO 模式。获得 IO 模式后,您可以使用接近复制该模式的工具测试和基准测试该模式下的实际存储性能。您可能需要一个可以向/从随机位置写入或读取的工具。同样,假设 Linux,您可以从
fio
. 您可能需要使用随机读/写选项。