為什麼我的 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 作為測試對象:

  • Intel® DC SSD S4500 480 GB,通過 SATA 3.2 連接,6 Gb/s;
  • 三星 970 EVO Plus 500GB,通過 PCIe 3.0 x4 連接,~31 Gbps。

測試在運行 Ubuntu 2255 的英特爾® 至強® 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 時失敗。 這就提出了兩個問題:

  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 性能更好,因此可以做出兩個假設:

  • 該磁盤專為類似計劃的負載而設計;
  • 磁盤“虛張聲勢”並忽略了命令。

如果您在斷電時執行測試,則可以注意到驅動器的不誠實行為。 您可以使用腳本進行檢查。 磁盤檢查器.pl, 那是 已確立的 2005年。

該腳本需要兩台物理機器——“服務器”和“客戶端”。 客戶端向被測驅動器寫入少量數據,調用 fsync,並向服務器發送有關寫入內容的信息。

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

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

運行腳本後,有必要將“客戶端”斷電,並在幾分鐘內不要恢復供電。 重要的是要斷開測試對象的電源,而不僅僅是執行硬關機。 一段時間後,可以連接服務器並將其加載到操作系統中。 啟動操作系統後,您需要重新啟動 磁盤檢查器.pl, 但有一個論點 確認.

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

檢查結束時,您將看到錯誤數。 如果它們為 0,則磁盤通過了測試。 要排除對磁盤成功的情況組合,可以重複多次實驗。

我們的 S4500 沒有顯示掉電錯誤,這意味著它已準備好承受大量 fsync 調用的負載。

結論

在選擇磁盤或整個現成的配置時,您應該牢記需要解決的任務的具體情況。 乍一看,NVMe,即帶有 PCIe 接口的固態硬盤,似乎比“經典”的 SATA 固態硬盤更快。 然而,正如我們今天所了解的那樣,在特定條件下和某些任務中,情況可能並非如此。

從 IaaS 提供商處租用時如何測試服務器組件?
我們在評論中等你。

為什麼我的 NVMe 比 SSD 慢?

來源: www.habr.com

添加評論