我已经使用fio对我的SSD进行了基准测试。然而,当指定fsync=1
(在每个write()
之后将脏缓冲区同步到磁盘)参数时,我对报告的延迟感到困惑。
$ fio --name=test_seq_write --filename=test_seq --size=2G --readwrite=write --fsync=1
test_seq_write: (g=0): rw=write, bs=4K-4K/4K-4K/4K-4K, ioengine=sync, iodepth=1
fio-2.1.3
Starting 1 process
test_seq_write: Laying out IO file(s) (1 file(s) / 2048MB)
Jobs: 1 (f=1): [W] [100.0% done] [0KB/31968KB/0KB /s] [0/7992/0 iops] [eta 00m:00s]
test_seq_write: (groupid=0, jobs=1): err= 0: pid=10994: Thu Oct 26 09:09:19 2017
write: io=2048.0MB, bw=35647KB/s, iops=8911, runt= 58831msec
clat (usec): min=2, max=1099, avg= 9.42, stdev=18.19
lat (usec): min=2, max=1099, avg= 9.56, stdev=18.28
这里,iops是8911,所以延迟应该大约在100us左右。然而,报告的延迟为9us。我很好奇fio是否包括fsync
的时间?我正在阅读fio文档,但没有找到任何解释。
fio 3.5或更高版本现在可以报告fsync延迟!在进行符合以下所有条件的工作负载时,您将看到此信息:
- 执行某种形式的写入
- 有一个
fsync/fdatasync/sync_file_range
集合 --output-format
是正常的(会有一个fsync/fdasync/sync_file_range部分)或json/json+(值记录在"sync"方向下)
下面是一个显示fsync延迟的正常输出示例:
$ ./fio --filename=/tmp/fio.tmp --size=1m --bs=512 --name=go --rw=write --fdatasync=1
go: (g=0): rw=write, bs=(R) 512B-512B, (W) 512B-512B, (T) 512B-512B, ioengine=psync, iodepth=1
[...]
go: (groupid=0, jobs=1): err= 0: pid=26958: Wed Feb 21 14:06:11 2018
write: IOPS=512k, BW=250MiB/s (262MB/s)(1024KiB/4msec)
clat (nsec): min=673, max=12144, avg=709.40, stdev=260.94
[...]
lat (usec) : 2=0.05%, 4=0.05%, 20=0.05%
fsync/fdatasync/sync_file_range:
sync (nsec): min=353, max=5307, avg=364.78, stdev=115.66
sync percentiles (nsec):
| 1.00th=[ 358], 5.00th=[ 358], 10.00th=[ 358], 20.00th=[ 362],
| 30.00th=[ 362], 40.00th=[ 362], 50.00th=[ 362], 60.00th=[ 362],
| 70.00th=[ 362], 80.00th=[ 362], 90.00th=[ 366], 95.00th=[ 366],
| 99.00th=[ 370], 99.50th=[ 370], 99.90th=[ 402], 99.95th=[ 2064],
| 99.99th=[ 5280]
[...]
因此,在回答您的问题时:
我很好奇fio是否包括
fsync
的时间?
在fio 3.3及以下版本中否(请参阅中的更新https://stackoverflow.com/a/46968852/9109338)。在fio 3.5及以上版本中,有点-fio在lat/clat延迟中不包括fsync(毕竟它不知道应该将fsync延迟归因于什么I/O,因为它无法检索到这些信息),但它自己计算和报告fsync延迟。
。看看我们目前发布的fio:https://github.com/axboe/fio/releases)
以下答案适用于fio 3.4及以上版本。有关fio 3.5及更新版本,请参阅稍后对此问题的回答。
fsyncs是常规I/O的独立fio操作(请参阅https://github.com/axboe/fio/blob/0bcf41cdc22dfee6b3f3b2ba9a533b4b103c70c2/io_u.c#L2170对于它们排队的位置),所以是的,它们应该被计数。[更新]但是,fio明确地将非读、写或修剪的I/O排除在统计数据收集之外(请参阅https://github.com/axboe/fio/blob/0bcf41cdc22dfee6b3f3b2ba9a533b4b103c70c2/io_u.c#L1823)。
所以
fio是否包括fsync的时间[在I/O延迟统计信息中]?
No fio不将fsync时间包括在延迟统计中。fsync将影响总带宽,但这将是不可分配的。
注意:fsync是一项繁重的操作,因为在Linux上它可以确保:
- I/O已被确认为由"磁盘"接收,并且不只是在Linux的页面缓存中
- 与整个文件关联的元数据已刷新到磁盘。由于复杂的原因,这可能意味着你最终也要等待其他文件的数据/元数据被刷新
- "磁盘"已确认I/O已达到其上的稳定存储(即,它不只是在无法承受断电的"磁盘"缓存中)
通常在进行基准测试时,您更感兴趣的是只确保1。因为至少在那时,您更接近于测试磁盘的速度(与Linux的缓存相反),而其他要点则是确保数据完整性。如果情况也是如此,我建议您在fio中使用direct=1,并停止使用fsync,因为这样每个I/O都会绕过Linux的页面缓存,直到磁盘确认收到I/O后才会返回。因此,每个I/O都会在其时间中内置"到磁盘的延迟",但如前所述,这并不意味着第2点或第3点。还要注意,并不是所有的文件系统都支持这个选项(这很遗憾)。
【原创猜测】
然而,也可能是写I/O很快完成,fsyncs很快完成但每次提交之间的空间为非零的情况(主要是由于fio必须完成工作)。所以做I/O->I/O完成->做非I/O工作->做I/O等。因此,您无法从所实现的IOP推断出I/O延迟(您只能给它一个上限)。
PS:您可以使用现代fio版本打开每次I/O日志记录(http://fio.readthedocs.io/en/latest/fio_doc.html#cmdoption-arg写入lat日志,http://fio.readthedocs.io/en/latest/fio_doc.html#log-文件格式,http://fio.readthedocs.io/en/latest/fio_doc.html#cmdoption-arg-log avg msec(log_avg_msec必须为0/unset)),但请注意,fsyncs也不受此日志记录的约束。请确保将日志保存在不会干扰测试的地方,并注意每次I/O日志的增长速度极快,因此在这种模式下最好不要进行太多I/O。
PPS:这个问题最好发到fio邮件列表(https://github.com/axboe/fio/blob/fio-3.1/README#L58)。