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 中に、オペレーティング システムはディスクとの通信を最適化しようとします。 したがって、オペレーティング システムは、ドライブへの XNUMX 回のアクセスでできるだけ多くのデータを書き込もうとします。

fsync を使用することの影響を具体的な例で示してみましょう。 テストドライブとして次の SSD を用意しています。

  • Intel® DC SSD S4500 480 GB、SATA 3.2、6 Gbit/s 経由で接続。
  • Samsung 970 EVO Plus 500GB、PCIe 3.0 x4、~31 Gbit/s 経由で接続。

テストは、Ubuntu 2255 を実行している Intel® Xeon® W-20.04 で実施されます。 Sysbench 1.0.18 はディスクのテストに使用されます。 ディスク上に 4 つのパーティションが作成され、ext100 としてフォーマットされています。 テストの準備には、XNUMX 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 が使用される場合には負けることは容易にわかります。 これにより、次の XNUMX つの疑問が生じます。

  1. fsync を使用しないテストでの読み取り速度がチャネルの物理帯域幅を超えるのはなぜですか?
  2. サーバーセグメント SSD が大量の fsync リクエストの処理に優れているのはなぜですか?

最初の質問に対する答えは簡単です。sysbench はゼロで埋められたファイルを生成します。 したがって、テストは 100 ギガバイトのゼロに対して実行されました。 データは非常に均一で予測可能なため、さまざまな OS の最適化が機能し、実行が大幅に高速化されます。

すべての 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 のパフォーマンスが低下する傾向がはっきりとわかります。 XNUMX 番目の質問への回答に進むことができます。

最適化またはブラフ

前に、データはバッファに保存されると述べましたが、これは重要ではないため、どのバッファであるかは指定しませんでした。 ここでは、オペレーティング システムの複雑さについては詳しく説明せず、一般的な XNUMX 種類のバッファについて説明します。

  • プログラム;
  • ハードウェア。

ソフトウェア バッファはオペレーティング システムに存在するバッファを指し、ハードウェア バッファはディスク コントローラの揮発性メモリを指します。 fsync システム コールは、バッファからメイン ストレージにデータを書き込むコマンドをドライブに送信しますが、コマンドが正しく実行されたことを確認する方法はありません。

SSD が最良の結果を示すため、次の XNUMX つの仮定ができます。

  • ディスクは同様の負荷向けに設計されています。
  • ディスクは「ブラフ」し、コマンドを無視します。

電源損失テストを実施すると、ドライブの不正な動作に気づくことができます。 これはスクリプトで確認できます ディスクチェッカー.plどれでした 作成 2005年間インチ

このスクリプトには、「サーバー」と「クライアント」という XNUMX つの物理マシンが必要です。 クライアントはテスト対象のディスクに少量のデータを書き込み、fsync を呼び出し、書き込まれた内容に関する情報をサーバーに送信します。

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

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

スクリプトを実行した後は、「クライアント」の電源を切り、数分間は電源を戻さないでください。 単に強制的にシャットダウンするだけでなく、検査を受ける人の電気を遮断することが重要です。 しばらくすると、サーバーに接続して OS にロードできるようになります。 OSをロードした後、再度起動する必要があります ディスクチェッカー.pl、ただし引数付き 確認する.

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

チェックの最後に、エラーの数が表示されます。 0 がある場合、ディスクはテストに合格しています。 円盤の幸運な偶然を排除するために、実験を数回繰り返すことができます。

当社の S4500 は、電源が失われたときにもエラーを表示しませんでした。これは、多くの fsync 呼び出しを伴うワークロードに対応できることを意味します。

まとめ

ディスクまたは既製の構成全体を選択するときは、解決する必要がある問題の詳細を覚えておく必要があります。 一見すると、NVMe、つまり PCIe インターフェイスを備えた SSD が「クラシック」SATA SSD よりも高速であることは明らかです。 ただし、今日学んだように、特定の条件や特定のタスクでは、これが当てはまらない場合があります。

IaaS プロバイダーからレンタルする場合、サーバー コンポーネントをどのようにテストしますか?
コメントお待ちしております。

NVMe が SSD よりも遅いのはなぜですか?

出所: habr.com

コメントを追加します