LinuxのVPSでNVMeディスクを正しく検証する方法
VPSのストレージが本当にNVMeか確認します。lsblkやsysfs、nvme-cliでの確認に加え、virtioが物理ディスクを隠蔽する仕組みと、fioを用いたレイテンシ測定による決定的な検証手順を解説します。
Linux で NVMe ディスクを 4 ステップで確認する
Linux VPS 上の NVMe ディスクを確認するには、4 つのチェックを順番に実行します。まず lsblk でデバイス名を確認し、次に sysfs の rotational フラグとバスパスを確認します。その後、nvme list で実際の NVMe コントローラーかどうかを調べ、最後に短時間の fio を実行します。これは、ホスト側では偽装できない 1 つの数値を確認するためです。最初の 3 つは、それぞれ 1 秒ほどで完了します。最後のチェックで判断が確定します。多くの VPS プラットフォームでは、ハイパーバイザーが物理ディスクをゲストから隠しているためです。
NVMe(non-volatile memory express)は、PCIe(peripheral component interconnect express)レーン経由でフラッシュストレージと通信するプロトコルです。回転ディスク向けに設計された SATA および AHCI の経路を置き換えました。CPU とフラッシュの間にあるキューイングのボトルネックを取り除くため、高速に動作します。仮想マシン内でこのプロトコルを直接扱うことは、ほとんどありません。ゲストからは、ホストが用意した仮想ディスクを扱います。そのため、ゲスト内のデバイス名が示すのはラック内のメディアではなく、ドライバーです。
Step 1: lsblk の出力内容
lsblk は、カーネルが管理するブロックデバイスの一覧を読み取ります。-d フラグを指定するとパーティションが非表示になり、ディスクごとに 1 行だけ表示されます。
lsblk -d -o NAME,ROTA,SIZE,TYPE,TRAN,MODELKVM VPS では、通常、次のように表示されます。
NAME ROTA SIZE TYPE TRAN MODEL
vda 1 80G disk virtioLinux サーバーでは、ほとんどの場合、次の 3 種類の命名パターンに該当します。
nvme0n1は NVMe コントローラー 0 の namespace 1 です。ゲストは、物理またはエミュレートされた NVMe デバイスを使用しています。sdaは SCSI 層です。実際の SATA ディスクと SAS ディスクに加えて、virtio-scsi ドライバーのデバイスもここに表示されます。vdaは virtio-blk です。多くの KVM ホストがデフォルトで使用する準仮想化ブロックドライバーです。
TRAN(transport)列には、NVMe デバイスの場合は nvme、ゲストから直接認識できる SATA ディスクの場合は sata と表示されます。virtio-blk では、現在の util-linux リリースは virtio を表示します。これは lsblk が vd デバイス名から推測した値です。古いリリースでは空欄になります。いずれの場合も、ゲストが報告できる物理的な transport はありません。MODEL も同じ理由で空欄になります。VPS で model 文字列が空欄になるのは正常であり、ハードウェアについての情報は得られません。
手順 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 では取得元がありません。virtio-blk 仕様には、メディアの種類や回転速度を示す feature bit がなく、Linux の virtio-blk ドライバーはすべてのディスクを rotational として扱うためです。そのため、vda はオールフラッシュのホスト上でも通常 1 を返します。ただし、udev ルールによって 0 に強制されている場合を除きます。virtio-scsi sda では、ホストが設定した値になります。したがって、VPS 内ではこのフラグだけでハードディスクの有無を判断できません。1 だけでは、サポートへの問い合わせ理由にはなりません。これを確認するには、以下の fio テストを実行します。
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 の名前を 1 文字も変更せずに、実際に得られる性能を変えます。したがって、名前は調査の出発点であって、終点ではありません。まだプランを選んでいる場合は、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 のように表示され、その下に fio が clat ブロックを出力します。clat は完了レイテンシです。fio が読み取りを送信してから、kernel がデータを返すまでの時間を示します。clat percentiles リストで avg の値を確認し、続いて 99.00th パーセンタイルを確認します。平均値からストレージクラスが分かります。99 パーセンタイルから、読み取りの遅い方 1% がどの程度遅いかが分かります。共有ホストでの競合は、通常ここに最初に現れます。
fio は、値が小さい場合はレイテンシをマイクロ秒で表示し、値が大きい場合はミリ秒に切り替えます。比較する前に、その行の単位を確認してください。
NVMe クラスと SATA クラスを分ける数値
以下の数値は、2026 年 8 月時点でベンダーのドキュメントとコミュニティーのベンチマークから集めた、単一ジョブによる queue depth 1 の 4k ランダム読み取りで一般的に公開されている値です。比較用の範囲であり、実際のサーバーで測定した値ではありません。
このグラフのデータ
[
{
"label": "Local NVMe",
"avg_latency_us": 110
},
{
"label": "Local SATA SSD",
"avg_latency_us": 320
},
{
"label": "Network block storage",
"avg_latency_us": 900
}
]このグラフのデータ
[
{
"label": "Local NVMe",
"iops": "9,000"
},
{
"label": "Local SATA SSD",
"iops": "3,100"
},
{
"label": "Network block storage",
"iops": "1,100"
}
]ローカルの NVMe ボリュームは、4k ランダム読み取り 1 回におよそ 110 マイクロ秒かかり、queue depth 1 で約 9,000 IOPS に達します。ローカルの SATA SSD は約 320 マイクロ秒、3,100 IOPS です。ネットワーク接続型のブロックストレージは約 900 マイクロ秒、1,100 IOPS になります。ホスト側のキャッシュにない読み取りは、フラッシュに到達する前にネットワークを通過する必要があるためです。
queue depth 1 では、この 2 つの列はほぼ同じ事実を別の形で示しています。一度に処理中の読み取りが 1 件だけの場合、スループットはおよそレイテンシーの逆数になります。ただし、リクエストごとのオーバーヘッドを考慮すると少し低下します。平均値が 110 マイクロ秒に近く、320 マイクロ秒から遠い場合、lsblk がそのデバイスを何と呼んでいるかにかかわらず、ストレージは NVMe クラスです。900 マイクロ秒に近い場合は、ローカルのフラッシュより遅い経路が含まれているか、ホストがボリュームの IOPS を制限しています。QEMU などのハイパーバイザーは、基盤となるストレージに関係なく、この制限を行うことがあります。いずれの場合も、ホストのドライブについて販売ページに何と記載されていても、ボリュームは NVMe クラスのレイテンシーを実現していません。
不満を言う前に複数回実行する
1回の実行はサンプルに過ぎず、結果ではありません。VPSはディスクを共有しているため、隣接する利用者の負荷が高いと、10分間だけレイテンシが倍増し、その後解消されることがあります。また、一部のプラットフォームではバーストクレジットが付与されるため、テスト開始直後の数分間は非常に良好な結果が出ます。同じコマンドを時間帯を変えて3〜4回実行し、最高の結果ではなく最悪の結果を比較してください。1回の悪い結果は一時的な状況に過ぎません。パターン化して初めてサポートチケットに値する障害となり、タイムスタンプ付きの fio 出力を3つ添付することで、より説得力のあるチケットになります。CPUやネットワークを含めたディスク以外の広範な状況を把握するには、VPSのフルベンチマーク実行において、他のサブシステムに対しても同様の規律でテストを行ってください。
回答の取り扱いについて
レイテンシが NVMe の範囲内であれば、デバイス名を気にする必要はありません。vda はダウングレードではありません。ほとんどのホストが提供する中で最も高速な仮想ディスクドライバーであり、これこそが推奨される構成です。
ローカル NVMe として販売されているプランで、レイテンシがネットワークストレージの範囲にある場合、具体的かつ再現可能な主張が可能です。実行した正確な fio コマンド、平均完了レイテンシ、および実行日時を記録してください。これはフォーラムでの議論ではなく、サポートチケットの対象です。送信前に、ディスクが単に満杯ではないか、あるいは激しく断片化していないかを確認し、テスト中にサーバー上で他の高負荷な書き込みが行われていないことを確認してください。
このチェックは、動作が遅いと感じた時ではなく、プロビジョニングした当日に実行し、後で比較するためのベースラインを作成してください。これは、ファイアウォールや SSH 鍵の設定と並んで、新しい VPS の最初の 10 分間の作業に自然に組み込めます。ストレージ階層の違いがまだ不明瞭な場合は、SSD VPS が実際に提供するもので、この前提となる知識を補完してください。
FAQ
lsblk でホストが NVMe を示しているのに /dev/vda と表示されるのはなぜですか?
`vda` はホストのハードウェアではなく、ゲスト内の virtio-blk ドライバーを示すためです。KVM ハイパーバイザーは、ファイル、論理ボリューム、またはデータセットをバックエンドとする準仮想化ブロックデバイスをゲストに提示します。そのバックエンドが NVMe ドライブ上にあっても、ゲストがそれを認識するとは限りません。この名前が示すのは仮想化層です。記憶媒体の種類を示すのは、レイテンシーの測定値だけです。
rotational 0 なら NVMe ディスクだと証明できますか?
いいえ。`/sys/block/<dev>/queue/rotational が 0 を保持している場合、カーネルはそのデバイスを回転プラッター付きとして扱っていないことを示します。ただし、VPS 内ではこれは測定値ではなく設定値です。virtio-blk には記憶媒体の種類を示す機能ビットがありません。また、何かが上書きしない限り、Linux の virtio-blk ドライバーはすべてのディスクに対して 1 を報告します。そのため、そこにある 0 は、通常、誰かが手動で設定した値です。これは NVMe と SATA SSD を区別できません。ローカルフラッシュとネットワークボリュームも区別できません。VPS 内の 1` もハードドライブの存在を証明しないため、このフラグではなく fio のレイテンシーを基に判断してください。
VPS で nvme list が空になるのはなぜですか?
ゲストに 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 マイクロ秒なら、ネットワーク接続ストレージ、またはホストがスロットリングしているボリュームを示します。ネットワーク接続ストレージでは、ホストのキャッシュにない読み取りがネットワークを経由します。これらは August 2026 時点で一般的に公開されている目安です。正確な数値ではなく桁の違いを比較してください。結論を出す前に、時間帯を変えて測定を繰り返してください。