为什么我的 NVMe 比 SSD 慢?

为什么我的 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, "42n", 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 2255 的 Intel® Xeon® W-20.04 上进行。 为了测试磁盘,使用 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 时,NVMe 就输了。 这提出了两个问题:

  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年。

该脚本需要两台物理机 - “服务器”和“客户端”。 客户端将少量数据写入被测驱动器,调用 fsync,并向服务器发送有关写入内容的信息。

# Запускается на сервере
./diskchecker.pl -l [port]

# Запускается на клиенте
./diskchecker.pl -s <server[:port]> create <file> <size_in_MB>

运行脚本后,需要将“客户端”断电,并在几分钟内不要恢复供电。 重要的是断开测试对象的电源,而不仅仅是执行硬关机。 一段时间后,服务器可以连接并加载到操作系统中。 启动操作系统后,需要重新启动 磁盘检查器,但有一个参数 确认.

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

检查结束时,您将看到错误数。 如果它们为 0,则磁盘通过测试。 为了排除磁盘成功的组合情况,可以重复实验多次。

我们的 S4500 未显示断电错误,这意味着它已准备好承受大量 fsync 调用的负载。

结论

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

从 IaaS 提供商租用服务器组件时如何测试服务器组件?
我们在评论里等你。

为什么我的 NVMe 比 SSD 慢?

来源: habr.com

添加评论