如何更改python2.7执行的每个IO读写操作的大小?
我正在尝试使用AWS EBS HDD存储,它通过限制IO操作的数量和每个操作的大小来限制带宽。引用the AWS volume type specs:
** gp2/io1 based on 16 KiB I/O size, st1/sc1 based on 1 MiB I/O size
在我的机器上运行iostat -xmdtz 1
,典型的输出是这样的:
Device: rrqm/s wrqm/s r/s w/s rMB/s wMB/s avgrq-sz avgqu-sz await r_await w_await svctm %util
nvme1n1 0.00 0.00 1435.00 0.00 179.12 0.00 255.64 1.77 1.22 1.22 0.00 0.69 99.60
因此看起来IO大小python使用的是256KB。我的问题是:
如何将其更改为1MB,以实现AWS提供的全部带宽潜力?
虽然我认为python中的IO操作大小是由一些较低级别的模块(io
?)确定的,但代码的相关部分如下所示:x是一个memmapped numpy数组,加载方式如此
x = np.load("...", mmap_mode = 'r')
然后实际读取它的部分代码是此代码段中的最后一行:
shared_x_base = multiprocessing.Array(ctypes.c_uint32, n1*k, lock=False)
shared_x = np.ctypeslib.as_array(shared_x_base)
shared_x = shared_x.reshape(n1, k)
shared_x[:] = x[:]
编辑:对于写作,大小(和带宽)的初始激增,如下所示:
Device: rrqm/s wrqm/s r/s w/s rMB/s wMB/s avgrq-sz avgqu-sz await r_await w_await svctm %util
nvme1n1 0.00 0.00 29.00 2033.00 3.62 507.84 507.99 59.37 28.83 33.93 28.76 0.48 100.00
但后来它解决了这个问题:
Device: rrqm/s wrqm/s r/s w/s rMB/s wMB/s avgrq-sz avgqu-sz await r_await w_await svctm %util
nvme1n1 0.00 0.00 1673.00 0.00 207.12 0.00 253.55 1.78 1.06 1.06 0.00 0.59 98.80
编辑:我也尝试删除memmapping,只是使用np.load和np.save(this answer建议这是要走的路,无论哪种方式,我认为它将有助于澄清问题的根源是什么。性能更糟糕的是:
Device: rrqm/s wrqm/s r/s w/s rMB/s wMB/s avgrq-sz avgqu-sz await r_await w_await svctm %util
nvme1n1 0.00 0.00 589.00 0.00 73.62 0.00 256.00 1.88 3.19 3.19 0.00 1.68 99.20
由于我不太确定问题是否真的与python的IO操作大小有关(参见Martijn Pieters的非常有用的答案),我想更广泛地问:
如何调整系统参数以使np.load()和np.save()操作(有或没有memmapping)在AWS限制策略下以最大带宽工作?
您将数组作为memmory映射对象打开,它使用引擎盖下的mmap
module。最终使用mmap
system call并且不能进一步配置。
相反,mmaped文件的I / O块大小由内核控制,但可以通过mmap.PAGESIZE
值或getconf PAGESIZE
命令行发现。
您可以通过确保正在运行的内核中的transparent hugepages support is enabled来调整此大小。
但是,qazxsw poi统计信息受到内核I / O缓存调整参数的严重影响。来自qazxsw poi:
iostat命令生成可用于更改系统配置的报告,以更好地平衡物理磁盘之间的输入/输出负载。
你看到的第一个'爆发'是因为iostat
从系统启动时为你提供了整体系统统计信息:
iostat命令生成的第一个报告提供有关自系统引导以来的时间的统计信息。每个后续报告都涵盖自上次报告以来的时间。
不要将这些数字解释为由Python代码引起的。
如果要调整内核I / O缓存,请参阅iostat
manpage,但请注意AWS可能已经针对网络连接存储进行了适当调整。