为什么我的NVMe比我的SSD慢?



在本文中,我们将研究I / O子系统的一些细微差别及其对性能的影响。



几周前,我遇到一个问题,为什么一台服务器上的NVMe比另一台服务器上的SATA慢。我查看了服务器的特性,并意识到这是一个棘手的问题:NVMe来自用户细分市场,而SSD来自服务器细分市场。



显然,比较不同环境中不同细分市场的产品是不正确的,但这并不是一个全面的技术答案。让我们学习基础知识,实验并回答问题。



什么是fsync及其在哪里使用



为了加快驱动器的工作速度,需要对数据进行缓冲,即将其存储在易失性内存中,直到出现合适的机会将缓冲区的内容保存到驱动器中为止。 “机会”标准由操作系统和驱动器的特性确定。发生电源故障时,缓冲区中的所有数据将丢失。



您需要执行许多任务,以确保将文件中的更改写入驱动器,而不是写入中间缓冲区。通过使用符合POSIX的fsync系统调用,可以获得这种信心。 fsync调用启动从缓冲区到驱动器的强制写入。



让我们用一个简短的C程序形式的人工示例来演示缓冲区的效果。



#include <fcntl.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>

int main(void) {
    /*   answer.txt  ,    --  */
    int fd = open("answer.txt", O_WRONLY | O_CREAT);
    /*     */
    write(fd, "Answer to the Ultimate Question of Life, The Universe, and Everything: ", 71);
    /*  ,      10  */
    sleep(10);
    /*    */
    write(fd, "42\n", 3); 

    return 0;
}


这些注释很好地说明了程序中的动作顺序。文本“关于生命,宇宙等所有主要问题的答案”将由操作系统缓冲,并且如果您在“计算”期间通过按“重置”按钮来重新启动服务器,则该文件将为空。在我们的示例中,文本丢失不是问题,因此不需要fsync。数据库对此并不乐观。



数据库是复杂的程序,可同时处理许多文件,因此,他们希望确保将写入的数据保存在驱动器上,因为数据库中数据的一致性取决于它。该数据库旨在记录所有已完成的事务,并随时准备停电。这种行为迫使我们一直大量使用fsync。



什么是fsync的频繁使用会影响



使用普通的I / O,由于外部驱动器在内存层次结构中最慢,因此操作系统会尝试优化与磁盘的通信。因此,操作系统试图在一次对驱动器的调用中写入尽可能多的数据。



让我们通过一个特定的示例来演示使用fsync的影响。我们有以下SSD作为测试对象:



  • 英特尔®DC SSD S4500 480 GB,通过SATA 3.2、6 Gb / s连接;
  • 三星970 EVO Plus 500GB,PCIe 3.0 x4,〜31 Gbps。


测试是在运行Ubuntu 20.04的Intel®Xeon®W-2255上进行的。Sysbench 1.0.18用于测试磁盘。在驱动器上创建一个分区,格式为ext4。测试准备工作包括创建100 GB文件:



sysbench --test=fileio --file-total-size=100G prepare


运行测试:



#  fsync
sysbench --num-threads=16 --test=fileio --file-test-mode=rndrw --file-fsync-freq=0 run

#  fsync   
sysbench --num-threads=16 --test=fileio --file-test-mode=rndrw --file-fsync-freq=1 run


测试结果列于表中。

测试 英特尔®S4500 三星970 EVO +
无需fsync即可读取,MiB / s 5734.89 9028.86
无需fsync,MiB / s的录制 3823.26 6019.24
用fsync,MiB / s读取 37.76 3.27
Fsync录制,MiB / s 25.17 2.18
很容易看出,当操作系统本身决定如何使用磁盘时,来自客户端的NVMe无疑处于领先地位,而当使用fsync时,它会失败。这就提出了两个问题:



  1. 为什么在没有fsync的测试中,读取速度超过了物理带宽?
  2. 为什么服务器端SSD能够更好地处理大量fsync请求?


第一个问题的答案很简单:sysbench生成用零填充的文件。因此,测试是在100 GB的零上进行的。由于数据非常单调且可预测,因此各种操作系统优化都可以发挥作用,并且可以显着加快执行速度。



如果您对所有sysbench结果有疑问,可以使用fio。



#  fsync
fio --name=test1 --blocksize=16k --rw=randrw --iodepth=16 --runtime=60 --rwmixread=60 --fsync=0 --filename=/dev/sdb

#  fsync   
fio --name=test1 --blocksize=16k --rw=randrw --iodepth=16 --runtime=60 --rwmixread=60 --fsync=1 --filename=/dev/sdb
测试 英特尔®S4500 三星970 EVO +
无需fsync即可读取,MiB / s 45.5 178
无需fsync,MiB / s的录制 30.4 119
用fsync,MiB / s读取 32.6 20.9
Fsync录制,MiB / s 21.7 13.9
使用fsync时NVMe性能下降的趋势显而易见。您可以继续回答第二个问题。



优化或虚张声势



前面我们说过数据存储在缓冲区中,但是由于它并不重要,因此我们没有指定哪个。现在,我们将不深入介绍操作系统的复杂性,并重点介绍两种常见的缓冲区类型:



  • 程序;
  • 硬件。


软件缓冲区是指操作系统中的缓冲区,而硬件缓冲区是指磁盘控制器的易失性内存。fsync系统调用将命令发送到驱动器,以将数据从其缓冲区写入主存储器,但是它无法控制命令执行的正确性。



由于SSD的性能更好,因此可以做出两个假设:



  • 磁盘设计用于这种负载;
  • 磁盘虚张声势,并忽略该命令。


如果运行电源故障测试,则可以看到驱动器的不诚实行为。您可以使用2005创建diskchecker.pl脚本进行检查 该脚本需要两个物理机-“服务器”和“客户端”。客户端向被测磁盘写入少量数据,调用fsync,并向服务器发送有关写入内容的信息。







#   
./diskchecker.pl -l [port]

#   
./diskchecker.pl -s <server[:port]> create <file> <size_in_MB>


运行脚本后,有必要断开“客户端”的电源,并且几分钟不返回电源。重要的是断开被测人员的电源,而不仅仅是执行硬关机。一段时间后,可以连接服务器并将其加载到OS中。操作系统启动后,您需要再次运行diskchecker.pl,但要使用verify参数



./diskchecker.pl -s <server[:port]> verify <file>


在检查结束时,您将看到错误数量。如果为0,则表明磁盘通过了测试。要排除光盘成功的多种情况,可以重复进行几次实验。



我们的S4500没有出现功率损耗错误,因此可以说它已经为许多fsync调用的负载做好了准备。



结论



在选择磁盘或完成现成的配置时,您应该记住需要解决的任务的细节。乍一看,NVMe(即具有PCIe接口的SSD)似乎比“经典” SATA SSD更快。但是,正如我们今天所了解的,在特定条件下和某些任务下,情况可能并非如此。



从IaaS提供商租用时如何测试服务器组件?

我们正在等待您的评论。






All Articles