我最近在一台新服务器上做了一些性能测试(使用dd),想知道为什么读取性能比写入性能差这么多?难道不应该换个方式吗?
两次测试中文件大小均为 550GB,读取:以秒为单位:3704 以 MB/s 为单位:148
并写入: 以秒为单位: 1539 以 MB/s 为单位: 357
写入命令:
time sh -c "dd if=/dev/zero of=/local/postgresql/bigfile
bs=8k count=67108864 && sync"
读取命令:
time dd if=/local/postgresql/bigfile of=/dev/null bs=8k
bash时间命令输出:
real: 61m44.335s
user: 0m12.721s
sys: 10m35.884s
Bonnie++ 结果命令:
bonnie++ -f -D -n 0 -u root -d /local/postgresql/
结果是文件大小是 RAM 大小的两倍。
写:
419 918 K/秒
读:
~ 187 000 K/秒
答案1
您需要使用写入同步标志来测试性能,以确保您实际上是在磁盘上写入而不是在缓存上写入。用于conv=fdatasync
在写入结束后强制同步缓冲区。看这里了解详情。
time dd .... conv=fdatasync
对于读取测试,在测试之前丢弃缓存:
flush
echo 3 | sudo tee /proc/sys/vm/drop_caches
time dd ....
答案2
你用的命令是什么?dd
做非常与性能相关的不同事物取决于选项。
但从你写的内容来看,
我认为您正在读取小块,这些块将根据您的要求大致从磁盘中读取。
您可以写入小块,当内核认为有时间执行此操作时,这些小块将被写入磁盘,而不是在dd
将它们写出时。
这已经可以解释其中的差异了,对吧?
答案3
我非常怀疑您能否从中获得有意义的基准dd
。dd
只是向您展示了不同设备之间执行的大型顺序读取或大型顺序异步写入。只要您的工作负载主要包括在这些文件系统之间复制大文件,就可以了。不过,我怀疑这就是你的工作量。
最好的选择是分析磁盘使用情况并使用真实的 I/O 基准测试套件(链接bonnie++
或其他东西)来测试更改各种可调参数的效果。对于数据库,我期望有大量的随机读取。对主数据文件进行设置noatime
和执行操作data=writeback
(定期进行备份)可能是利用我们迄今为止所掌握的信息所能做的最好的事情。
要回答似乎是您更大的问题,这是因为异步写入(如由 进行的写入dd
)可以在内存中缓冲并提交到磁盘。他们是种类只要队列和缓冲区可以填满,您就必须等待它们再次可用(通过提交到磁盘),然后才能堆叠更多内容。
另一方面,读取在定义上是 I/O 绑定的,因此您通常不会进行相同的异步操作。您可以尝试read_ahead_kb
诸如此类的操作,以便将更多顺序数据读入内存,以应对不久的将来工作负载的要求。
这就是我目前所能想到的回答。如果您有任何疑问,请告诉我。