LinuxのVPSでNVMeディスクを正しく検証する方法
VPSのストレージが本当にNVMeか確認します。lsblkやsysfs、nvme-cliでの確認に加え、virtioが物理ディスクを隠蔽する仕組みと、fioを用いたレイテンシ測定による決定的な検証手順を解説します。
Linux で NVMe ディスクを検証する 4 つのステップ
Linux VPS 上の NVMe ディスクを検証するには、以下の 4 つのチェックを順に実行します。デバイス名の確認に lsblk、回転メディアかどうかの判定に sysfs の rotational フラグ、実際の NVMe コントローラーの確認に nvme list、そしてホスト側で偽装できない数値を特定するための短い fio の実行です。最初の 3 つは各 1 秒で完了します。最後のチェックが決定打となります。ほとんどの VPS プラットフォームでは、ハイパーバイザーが物理ディスクをゲストから隠蔽しているためです。
NVMe (non-volatile memory express) は、フラッシュストレージが PCIe (peripheral component interconnect express) レーン経由で通信するためのプロトコルです。これは回転ドライブ向けに設計された SATA や AHCI の経路を置き換えるもので、CPU とフラッシュ間のキューイングのボトルネックを解消するため高速です。仮想マシン内では、このプロトコルを直接扱うことはほとんどありません。ゲストはホストが構築した仮想ディスクと通信するため、ゲスト上のデバイス名はメディアそのものではなく、ドライバーを指し示しています。
ステップ 1: lsblk は何を表示するか
lsblk はカーネルのブロックデバイス一覧を読み取ります。-d フラグはパーティションを非表示にするため、ディスクごとに 1 行で表示されます。
lsblk -d -o NAME,ROTA,SIZE,TYPE,TRAN,MODELKVM VPS は通常、以下のように応答します。
NAME ROTA SIZE TYPE TRAN MODEL
vda 0 80G diskLinux サーバーのほとんどは、以下の 3 つの命名パターンに分類されます。
nvme0n1は NVMe コントローラー 0 上のネームスペース 1 です。ゲストは実機またはエミュレートされた NVMe デバイスを駆動しています。sdaは SCSI レイヤーです。物理的な SATA および SAS ディスク、そして virtio-scsi ドライバーがここに割り当てられます。vdaは virtio-blk であり、多くの KVM ホストがデフォルトで使用する準仮想化ブロックドライバーです。
TRAN (トランスポート) カラムは、NVMe デバイスであれば nvme、ゲストが直接認識できる SATA ディスクであれば sata と表示されます。virtio-blk の場合、ゲストが報告すべき物理トランスポートが存在しないため、通常は空欄になります。MODEL も同様の理由で空欄となります。VPS においてモデル文字列が空であることは正常であり、ハードウェアに関する情報は得られません。
ステップ 2: 回転ディスクの除外
DISK=$(lsblk -dno NAME,TYPE | awk '$2 == "disk" { print $1; exit }')
echo "checking $DISK"
cat "/sys/block/$DISK/queue/rotational"
readlink -f "/sys/block/$DISK"rotational ファイルには、カーネルがそのデバイスを回転プラッタと判断した場合は 1 が、それ以外の場合は 0 が格納されます。ベアメタル環境では、この値はドライブ自体から取得されます。virtio-blk 環境下ではホストが設定する機能ビットに依存するため、0 であっても単なるハードドライブではないと断定できるだけで、それ以上の証明にはなりません。いずれにせよ確認してください。SSD として販売されている製品で 1 と表示されるのは明らかな矛盾であり、サポート担当者が反論できない決定的な証拠となります。
readlink -f は sysfs のシンボリックリンクを解決し、デバイスが接続されているバスを表示します。
/sys/devices/pci0000:00/0000:00:05.0/virtio2/block/vdaパスに含まれる virtio という単語が、このステップの答えです。NVMe デバイスであれば nvme を含むパス(例: /sys/devices/pci0000:00/0000:01:00.0/nvme/nvme0/nvme0n1)が表示され、直接接続された ATA ディスクであれば ata1 を含むパスが表示されます。これは lsblk が出力する情報と同じですが、フォーマットされた列からではなくカーネルから直接取得するため、TRAN フィールドが空の場合に有用です。
ステップ 3: nvme-cli と PCI バスへの問い合わせ
sudo apt update
sudo apt install -y nvme-cli pciutils
sudo nvme list || echo "nvme-cli found no NVMe device"
lspci | grep -i -e nvme -e 'non-volatile' || echo "no NVMe controller on this guest's PCI bus"nvme list は、コントローラーのシリアル番号、モデル文字列、ファームウェアリビジョンとともに、名前空間ごとに 1 行ずつ出力します。テーブルが空であれば、ゲストに NVMe デバイスが公開されていません。lspci で一致する行が出力されない場合も同様で、ゲストから見える仮想 PCI バス上に NVMe コントローラーが存在しないことを意味します。どちらの結果も virtio VPS では正常であり、ホスト側に NVMe ドライブが存在しないという証拠にはなりません。
名前空間が表示された場合、nvme-cli で詳細を確認できます。sudo nvme id-ctrl /dev/nvme0 はコントローラーの識別情報を出力し、sudo nvme smart-log /dev/nvme0n1 は温度、通電時間、定格書き込み耐久性の使用率を出力します。これらのコマンドは、nvme list でデバイスがリストアップされた場合にのみ実行してください。どちらのコマンドも、開くための実在する /dev/nvme* ノードを必要とするためです。
NVMeホストであっても /dev/vda と表示される理由
ハイパーバイザーがゲストに見せるデバイスモデルを決定するため、その選択は基盤となるメディアとは無関係です。一般的な構成は以下の3つです。
- NVMeドライブ上のファイル、論理ボリューム、または ZFS データセットに対する virtio-blk または virtio-scsi。
vdaまたはsdaと表示されます。ストレージはNVMeですが、ゲスト側でそれを知る方法はありません。 - ストレージの種類を問わず、その手前に配置されたエミュレートされたNVMeコントローラー。SATAアレイや2ラック離れたネットワークボリュームにデータが書き込まれる場合でも、
nvme0n1と表示されます。 - PCIeパススルー。ホストが物理コントローラーを1つのゲストに直接割り当てます。実際のモデル文字列を含む本物の
nvme0n1が表示されます。これは共有VPSプランでは稀です。カードがその顧客専用になってしまうためです。
したがって、デバイス名はどちらの方向にも誤解を招く可能性があります。さらに悪いことに、ホストは書き込みとフラッシュメモリの間にライトバックキャッシュ、RAID層、または複製されたネットワークボリュームを介在させることがあります。これらは /sys 上のデバイス名を変更することなく、得られるパフォーマンスを変化させます。そのため、デバイス名は調査の出発点であって、終着点ではありません。プランを検討中であれば、NVMeストレージとSATA SSDストレージの違いで、各ティアが実際に支払う価値があるものかどうかを確認してください。
レイテンシこそが真の指標であるため、これを測定する
fio (flexible I/O tester) は、実際のファイルに対して実際の読み取りを発行し、それぞれの所要時間を報告します。ここでは小さなランダム読み取りが適切なワークロードとなります。これはメディアへの往復時間を露呈させるものであり、先読み(read-ahead)による最適化が効かないためです。
まずテストファイルを作成し、そのファイルシステムが非バッファ I/O を受け入れることを確認します。--direct=1 は O_DIRECT を指定してファイルを開きます。これによりページキャッシュをバイパスします。これがない場合、自身の RAM を測定することになり、ディスクでは不可能な数値を計測してしまいます。
sudo apt install -y fio
fio --name=prep --filename=/var/tmp/nvme-check.tmp --size=256M --bs=1M --rw=write --direct=1 --end_fsync=1 > /dev/null \
&& echo "unbuffered writes work here, the timing test is valid" \
|| echo "this filesystem refuses direct=1, so the timing test below will not run"もし拒否された旨が表示された場合、選択したパスは O_DIRECT をサポートしていないファイルシステム上にあります。コンテナの overlay ファイルシステムや一部のネットワークファイルシステムはこのような挙動を示します。VPS のルートファイルシステム上のディレクトリを選択して再度試してください。成功した場合は、以下の測定を実行します。
fio --name=randread4k --filename=/var/tmp/nvme-check.tmp --bs=4k --rw=randread \
--direct=1 --iodepth=1 --numjobs=1 --runtime=20 --time_based --group_reporting \
|| echo "fio stopped early, read its first line for the reason"
rm -f /var/tmp/nvme-check.tmpこの実行は意図的に制限を設けています。ジョブ数 1、キュー深度 1、20 秒間、データサイズ 256 MB です。ディスクを埋め尽くすことはなく、不正利用としてフラグが立てられることもありません。キュー深度 1 はこの問いに対する誠実な設定です。キューを深くすると、低速なデバイスが並列処理の裏に隠れてしまい、レイテンシが高いまま放置される可能性があるためです。
fio の出力結果の読み方
重要な行は2つです。サマリー行は read: IOPS=9012, BW=35.2MiB/s のように表示され、その下に clat ブロックが出力されます。clat は完了レイテンシであり、fio が読み取りを要求してからカーネルがデータを返すまでの時間です。avg の値を確認し、次に clat percentiles リスト内の 99.00th パーセンタイルを確認してください。平均値はストレージクラスを示します。99パーセンタイル値は、同じホスト上の他のユーザーによる影響でどれだけ待たされるかを示します。
fio は値が小さい場合はマイクロ秒単位で、大きい場合はミリ秒単位でレイテンシを表示します。値を比較する前に、必ず直前の行で単位を確認してください。
NVMe クラスと SATA クラスを分ける数値
以下の数値は、2026 年 8 月時点のベンダー資料およびコミュニティのベンチマークから収集した、キュー深さ 1 におけるシングルジョブ 4k ランダムリードの典型的な公開値です。これらは比較のための目安であり、サーバーの実測値ではありません。
The data behind this chart
[
{
"label": "Local NVMe",
"avg_latency_us": 110
},
{
"label": "Local SATA SSD",
"avg_latency_us": 320
},
{
"label": "Network block storage",
"avg_latency_us": 900
}
]The data behind this chart
[
{
"label": "Local NVMe",
"iops": "9,000"
},
{
"label": "Local SATA SSD",
"iops": "3,100"
},
{
"label": "Network block storage",
"iops": "1,100"
}
]ローカルの NVMe ボリュームは、4k ランダムリード 1 回あたり約 110 マイクロ秒で応答し、キュー深さ 1 で約 9,000 IOPS に達します。ローカルの SATA SSD は 320 マイクロ秒および 3,100 IOPS 前後です。ネットワーク接続されたブロックストレージは、フラッシュに到達する前に必ずネットワークホップを経由するため、約 900 マイクロ秒および 1,100 IOPS 程度となります。
キュー深さ 1 において、これら 2 つの列は同じ事実を異なる表現で示しています。一度に 1 回の読み取りを行う場合、スループットは単に 1 をレイテンシで割った値になるためです。平均値が 320 マイクロ秒よりも 110 マイクロ秒に近い場合、lsblk がそのデバイスを何と呼称していようと、使用しているのは NVMe クラスのストレージです。もし 900 マイクロ秒に近いのであれば、ローカルフラッシュよりも低速な何かが経路に存在しており、注文ページにある NVMe という表記は、ボリュームではなくホスト側のドライブを指していることになります。
不満を言う前に複数回実行する
1回の実行はサンプルに過ぎず、結果ではありません。VPSはディスクを共有しているため、隣接する利用者の負荷が高いと、10分間だけレイテンシが倍増し、その後解消されることがあります。また、一部のプラットフォームではバーストクレジットが付与されるため、テスト開始直後の数分間は非常に良好な結果が出ます。同じコマンドを時間帯を変えて3〜4回実行し、最高の結果ではなく最悪の結果を比較してください。1回の悪い結果は一時的な状況に過ぎません。パターン化して初めてサポートチケットに値する障害となり、タイムスタンプ付きの fio 出力を3つ添付することで、より説得力のあるチケットになります。CPUやネットワークを含めたディスク以外の広範な状況を把握するには、VPSのフルベンチマーク実行において、他のサブシステムに対しても同様の規律でテストを行ってください。
回答の取り扱いについて
レイテンシが NVMe の範囲内であれば、デバイス名を気にする必要はありません。vda はダウングレードではありません。ほとんどのホストが提供する中で最も高速な仮想ディスクドライバーであり、これこそが推奨される構成です。
ローカル NVMe として販売されているプランで、レイテンシがネットワークストレージの範囲にある場合、具体的かつ再現可能な主張が可能です。実行した正確な fio コマンド、平均完了レイテンシ、および実行日時を記録してください。これはフォーラムでの議論ではなく、サポートチケットの対象です。送信前に、ディスクが単に満杯ではないか、あるいは激しく断片化していないかを確認し、テスト中にサーバー上で他の高負荷な書き込みが行われていないことを確認してください。
このチェックは、動作が遅いと感じた時ではなく、プロビジョニングした当日に実行し、後で比較するためのベースラインを作成してください。これは、ファイアウォールや SSH 鍵の設定と並んで、新しい VPS の最初の 10 分間の作業に自然に組み込めます。ストレージ階層の違いがまだ不明瞭な場合は、SSD VPS が実際に提供するもので、この前提となる知識を補完してください。
FAQ
ホストが NVMe を宣伝しているのに、なぜ lsblk は /dev/vda と表示するのですか?
それは、vda がゲスト OS 内の virtio-blk ドライバーの名前を示しており、ホスト側のハードウェア名ではないためです。KVM ハイパーバイザーは、ファイル、論理ボリューム、またはデータセットをバックエンドとする準仮想化ブロックデバイスを提供します。このバックエンドストレージが NVMe ドライブ上に配置されていても、ゲスト OS がそれを知ることはありません。デバイス名は仮想化レイヤーを記述するものであり、メディアの特性はレイテンシの測定によってのみ判別可能です。
rotational 0 は NVMe ディスクであることの証明になりますか?
いいえ。/sys/block/<dev>/queue/rotational が 0 を保持していることは、カーネルがそのデバイスを回転プラッタを持つディスクではないと認識していることを意味します。virtio 環境下では、この値はホストが選択した機能ビットによって設定されます。これは通常のハードディスクではないことを示しますが、NVMe と SATA SSD の区別や、ローカルのフラッシュストレージとネットワークボリュームの区別はできません。1 は、ソリッドステートストレージとして販売されている製品の仕様と矛盾する場合があるため、確認する価値はあります。
VPS で nvme list が空になるのはなぜですか?
ゲスト OS に対して NVMe コントローラーが公開されていないためです。nvme list および lspci はどちらも仮想マシンから見える情報を読み取りますが、virtio-blk や virtio-scsi ディスクは列挙すべき NVMe コントローラーを提示しません。ほとんどの VPS プランにおいてテーブルが空になるのは正常な結果であり、ホストが NVMe ドライブを搭載していないことの証明にはなりません。sudo apt install -y nvme-cli で nvme-cli をインストールしても、コントローラーがパススルーされていない限り、テーブルは空のままとなります。
どのような fio の結果が NVMe クラスのストレージとみなされますか?
キュー深度 1、4k ランダムリード、--direct=1 の条件下で、平均完了レイテンシが 110 マイクロ秒に近い場合は NVMe クラスであり、そこから概ね 9,000 IOPS が導かれます。320 マイクロ秒前後であれば SATA SSD、900 マイクロ秒前後であれば、各読み取りがネットワークホップを跨ぐネットワーク接続ストレージである可能性が高いです。これらは 2026 年 8 月時点の一般的な帯域の目安です。正確な数値ではなく桁数で比較し、結論を出す前に異なる時間帯で測定を繰り返してください。