Cách kiểm tra VPS có thật sự dùng NVMe trên Linux
Kiểm tra VPS từ guest bằng lsblk, sysfs, nvme-cli và fio. Tìm lỗi virtio che giấu đĩa vật lý, rồi đo latency trong một lượt chạy giới hạn.
Kiểm tra ổ đĩa NVMe trên Linux qua 4 bước
Để kiểm tra một ổ đĩa NVMe trên Linux VPS, hãy thực hiện lần lượt 4 bước: dùng lsblk để xác định tên thiết bị, kiểm tra cờ rotational và đường dẫn bus trong sysfs, dùng nvme list để xác nhận có controller NVMe thật, rồi chạy nhanh fio để kiểm tra con số duy nhất mà host không thể làm giả. Ba bước đầu chỉ mất khoảng 1 giây mỗi bước. Bước cuối sẽ cho câu trả lời, vì trên hầu hết nền tảng VPS, hypervisor ẩn ổ đĩa vật lý khỏi guest.
NVMe (non-volatile memory express) là giao thức mà thiết bị lưu trữ flash sử dụng qua các lane PCIe (peripheral component interconnect express). Giao thức này thay thế đường truyền SATA và AHCI vốn được thiết kế cho ổ đĩa quay. Nó nhanh hơn vì loại bỏ điểm nghẽn xếp hàng giữa CPU và flash. Bên trong một máy ảo, bạn hiếm khi thực sự sử dụng giao thức đó. Bạn làm việc với một ổ đĩa ảo do host tạo sẵn, nên tên thiết bị trong guest mô tả driver, không phải loại media trong rack.
Bước 1: lsblk hiển thị gì?
lsblk đọc danh sách thiết bị block của kernel. Cờ -d ẩn các partition, nên bạn thấy một dòng cho mỗi disk.
lsblk -d -o NAME,ROTA,SIZE,TYPE,TRAN,MODELKVM VPS thường hiển thị như sau:
NAME ROTA SIZE TYPE TRAN MODEL
vda 1 80G disk virtioBa mẫu tên này bao phủ gần như mọi Linux server:
nvme0n1là namespace 1 trên NVMe controller 0. Guest của bạn đang sử dụng thiết bị NVMe, thật hoặc được mô phỏng.sdalà lớp SCSI. Disk SATA và SAS thật sẽ xuất hiện ở đây, cũng như driver virtio-scsi.vdalà virtio-blk, driver block paravirtual mà hầu hết KVM host sử dụng mặc định.
Cột TRAN (transport) hiển thị nvme cho thiết bị NVMe và sata cho disk SATA mà guest có thể thấy trực tiếp. Với virtio-blk, các bản phát hành util-linux hiện tại in virtio. lsblk suy ra giá trị này từ tên thiết bị vd; các bản phát hành cũ hơn để trống. Dù theo cách nào thì guest cũng không có transport vật lý để báo cáo. MODEL cũng để trống vì cùng lý do. Chuỗi model trống trên VPS là bình thường và không cho bạn biết gì về phần cứng.
Bước 2: loại trừ ổ đĩa quay
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"Tệp rotational chứa 1 khi kernel xem thiết bị là loại có platter quay, và 0 trong các trường hợp khác. Trên bare metal, giá trị này do ổ đĩa cung cấp. Với virtio-blk, giá trị này không xuất phát từ đâu cả: đặc tả virtio-blk không có feature bit cho loại media hoặc tốc độ quay, còn driver virtio-blk của Linux đánh dấu mọi ổ đĩa là rotational. Vì vậy, vda thường đọc là 1 ngay cả trên host toàn bộ dùng flash, trừ khi có người buộc nó thành 0 bằng udev rule. Với sda virtio-scsi, giá trị này là giá trị host đã chọn để cấu hình. Do đó, bên trong VPS, flag này không thể xác định có hay không có hard drive, và riêng một 1 không đủ căn cứ để tạo support ticket. Bài kiểm tra fio bên dưới mới trả lời được câu hỏi đó.
readlink -f phân giải sysfs symlink và in ra bus mà thiết bị kết nối vào:
/sys/devices/pci0000:00/0000:00:05.0/virtio2/block/vdaTừ virtio trong đường dẫn đó là câu trả lời cho bước này. Thiết bị NVMe tạo ra đường dẫn chứa nvme, chẳng hạn /sys/devices/pci0000:00/0000:01:00.0/nvme/nvme0/nvme0n1, còn ổ ATA kết nối trực tiếp tạo ra đường dẫn chứa ata1. Đây là cùng thông tin mà lsblk đã in ra, nhưng được lấy trực tiếp từ kernel thay vì từ một cột đã format. Điều này hữu ích khi trường TRAN bị để trống.
Bước 3: truy vấn nvme-cli và bus 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 in một dòng cho mỗi namespace, kèm số serial, chuỗi model và phiên bản firmware của controller. Bảng trống nghĩa là guest của bạn không được cung cấp thiết bị NVMe nào. lspci không in ra dòng khớp nào cũng cho cùng kết luận theo hướng ngược lại: bus PCI ảo mà guest nhìn thấy không có controller NVMe. Cả hai kết quả trống đều là bình thường trên VPS dùng virtio và không kết quả nào chứng minh host không có ổ NVMe.
Nếu có namespace xuất hiện, nvme-cli có thể kiểm tra sâu hơn. sudo nvme id-ctrl /dev/nvme0 in thông tin nhận dạng của controller, còn sudo nvme smart-log /dev/nvme0n1 in nhiệt độ, số giờ đã bật nguồn và phần trăm dung lượng ghi định mức đã sử dụng. Chỉ chạy các lệnh đó khi nvme list thực sự liệt kê một thiết bị, vì cả hai lệnh đều cần mở một node /dev/nvme* thực tế.
Vì sao host thực sự dùng NVMe vẫn hiển thị /dev/vda
Hypervisor quyết định guest của bạn nhìn thấy model thiết bị nào. Lựa chọn đó độc lập với loại storage bên dưới. Có 3 kiểu triển khai phổ biến.
- virtio-blk hoặc virtio-scsi chạy trên một file, logical volume hoặc ZFS dataset nằm trên các ổ NVMe. Bạn sẽ thấy
vdahoặcsda. Storage bên dưới là NVMe. Guest không có cách nào biết được điều đó. - Một controller NVMe được emulation ở phía trước bất kỳ loại storage nào. Bạn sẽ thấy
nvme0n1, kể cả khi dữ liệu thực tế nằm trên một SATA array hoặc network volume cách đó 2 rack. - PCIe passthrough, trong đó host chuyển một controller vật lý cho riêng một guest. Bạn sẽ thấy
nvme0n1thực sự cùng chuỗi model thực. Cách này hiếm trên các gói shared VPS vì card đó sẽ được dành riêng cho một khách hàng.
Vì vậy, tên thiết bị có thể gây hiểu nhầm theo cả 2 hướng. Tệ hơn, host có thể đặt write-back cache, RAID layer hoặc replicated network volume giữa thao tác ghi của bạn và flash. Mỗi lớp này đều có thể thay đổi hiệu năng bạn nhận được mà không thay đổi bất kỳ tên nào trong /sys. Vì vậy, tên thiết bị là điểm bắt đầu, không phải điểm kết thúc. Nếu bạn vẫn đang chọn một gói, sự khác nhau giữa storage NVMe và SATA SSD giải thích giá trị thực tế của từng tier.
Đo latency mới là phép thử chính xác
fio (flexible I/O tester) thực hiện các thao tác đọc thực trên một file thực và báo thời gian của từng thao tác. Các thao tác đọc ngẫu nhiên với kích thước nhỏ là workload phù hợp ở đây. Chúng cho thấy đầy đủ thời gian round trip đến thiết bị lưu trữ và không thể được read-ahead phục vụ.
Trước tiên, hãy tạo file kiểm thử và xác nhận filesystem này chấp nhận unbuffered I/O. --direct=1 mở file bằng O_DIRECT, nhờ đó bỏ qua page cache. Nếu không dùng tùy chọn này, bạn đang đo RAM của chính mình và nhận được những con số mà không ổ đĩa nào có thể tạo ra.
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"Nếu lệnh in ra thông báo từ chối, path bạn chọn nằm trên filesystem không hỗ trợ O_DIRECT. Container overlay filesystem và một số network filesystem hoạt động theo cách này. Hãy chọn một directory trên root filesystem của VPS rồi thử lại. Nếu lệnh in ra thông báo thành công, hãy chạy phép đo:
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.tmpLần chạy này được giới hạn có chủ đích: một job, queue depth bằng 1, chạy trong twenty seconds và sử dụng 256 MB dữ liệu. Lệnh sẽ không làm đầy disk và cũng không khiến bạn bị đánh dấu là abuse. Queue depth bằng 1 cũng là thiết lập trung thực cho câu hỏi này, vì queue sâu cho phép thiết bị chậm che giấu latency bằng tính song song trong khi latency vẫn cao.
Đọc output của fio
Có 2 dòng cần chú ý. Dòng summary có dạng read: IOPS=9012, BW=35.2MiB/s. Bên dưới, fio in ra một block clat. clat là latency khi hoàn tất: khoảng thời gian từ lúc fio gửi yêu cầu đọc đến lúc kernel trả dữ liệu về. Đọc giá trị avg, rồi đọc percentile 99.00th trong danh sách clat percentiles. Giá trị trung bình cho biết storage class. Percentile 99 cho biết 1% lượt đọc chậm nhất mất bao lâu. Đây thường là nơi contention trên shared host xuất hiện đầu tiên.
Fio hiển thị latency theo microsecond khi giá trị nhỏ và chuyển sang millisecond khi giá trị lớn hơn. Kiểm tra unit trên dòng đó trước khi so sánh.
Những con số nào phân biệt storage class NVMe với SATA
Các giá trị dưới đây là những mức thường được công bố cho workload đọc ngẫu nhiên 4k, một job, queue depth 1. Các giá trị này được tổng hợp từ tài liệu của vendor và benchmark cộng đồng tính đến tháng 8 năm 2026. Đây là các khoảng tham chiếu để so sánh, không phải số đo từ server của bạn.
Dữ liệu đằng sau biểu đồ này
[
{
"label": "Local NVMe",
"avg_latency_us": 110
},
{
"label": "Local SATA SSD",
"avg_latency_us": 320
},
{
"label": "Network block storage",
"avg_latency_us": 900
}
]Dữ liệu đằng sau biểu đồ này
[
{
"label": "Local NVMe",
"iops": "9,000"
},
{
"label": "Local SATA SSD",
"iops": "3,100"
},
{
"label": "Network block storage",
"iops": "1,100"
}
]Một volume NVMe cục bộ xử lý một lần đọc ngẫu nhiên 4k trong khoảng 110 microsecond và đạt khoảng 9,000 IOPS ở queue depth 1. Một SATA SSD cục bộ có độ trễ khoảng 320 microsecond và đạt 3,100 IOPS. Block storage gắn qua network có độ trễ khoảng 900 microsecond và đạt 1,100 IOPS, vì một lần đọc không có trong cache phía host phải đi qua network trước khi đến flash.
Ở queue depth 1, hai cột đó gần như chỉ là cùng một thông tin được trình bày hai lần: khi mỗi lần chỉ có một request đang thực hiện, throughput xấp xỉ bằng một chia cho độ trễ, rồi thấp hơn một chút sau khi tính overhead của từng request. Nếu độ trễ trung bình của bạn gần 110 hơn 320 microsecond, bạn đang dùng storage class NVMe, bất kể lsblk gọi thiết bị đó là gì. Nếu độ trễ gần 900 microsecond hơn, hoặc trên đường xử lý có thành phần chậm hơn flash cục bộ, hoặc host đang giới hạn IOPS của volume. Các hypervisor như QEMU có thể làm việc này, bất kể storage bên dưới là gì. Trong cả hai trường hợp, volume của bạn không cung cấp độ trễ thuộc storage class NVMe, dù trang đặt hàng có ghi gì về các ổ đĩa trên host.
Chạy nhiều hơn một lần trước khi phàn nàn
Một lần chạy chỉ là mẫu đo, chưa phải kết quả. VPS dùng chung ổ đĩa, nên một máy thuê cùng máy chủ đang bận có thể làm độ trễ của bạn tăng gấp đôi trong mười phút rồi biến mất. Một số nền tảng cũng cấp burst credit, khiến những phút đầu của bất kỳ bài kiểm tra nào trông rất tốt. Hãy chạy cùng một lệnh ba hoặc bốn lần vào các thời điểm khác nhau trong ngày và so sánh kết quả tệ nhất, không phải kết quả tốt nhất. Một lần chạy xấu chỉ là biến động nhất thời. Một xu hướng lặp lại là lỗi đáng để gửi support ticket, và ticket sẽ thuyết phục hơn nếu đính kèm ba output của fio có timestamp. Để có bức tranh đầy đủ hơn, bao gồm cả CPU và network bên cạnh disk, một lần benchmark VPS đầy đủ áp dụng cùng nguyên tắc cho các subsystem khác.
Cần làm gì với kết quả
Nếu độ trễ nằm trong dải NVMe, hãy bỏ qua tên thiết bị và tiếp tục. vda không phải là lựa chọn kém hơn. Đây là driver đĩa ảo nhanh nhất mà hầu hết host cung cấp, và đó là lựa chọn bạn cần.
Nếu độ trễ nằm trong dải storage qua network trong khi gói dịch vụ được bán là NVMe cục bộ, bạn có một nhận định cụ thể và có thể tái hiện: lệnh fio chính xác, độ trễ hoàn tất trung bình và thời điểm bạn chạy lệnh. Đây là nội dung để tạo support ticket, không phải tranh luận trên forum. Trước khi gửi, hãy xác nhận disk không chỉ đơn giản là đã đầy hoặc bị phân mảnh nghiêm trọng. Đồng thời xác nhận không có tiến trình nào trên máy đang ghi dữ liệu với tải cao trong lúc bạn kiểm tra.
Hãy chạy kiểm tra này ngay trong ngày provision VPS, không phải đợi đến khi có cảm giác máy chạy chậm. Như vậy, bạn có baseline để so sánh về sau. Việc này phù hợp với 10 phút đầu tiên khi thiết lập một VPS mới, cùng với việc cấu hình firewall và SSH keys. Nếu bạn vẫn chưa phân biệt rõ các tier storage, VPS SSD thực sự cung cấp cho bạn những gì sẽ giải thích phần nền tảng của vấn đề này.
FAQ
Vì sao lsblk hiển thị /dev/vda khi nhà cung cấp quảng cáo NVMe?
Vì vda là tên của driver virtio-blk trong guest, không phải tên phần cứng trên host. Hypervisor KVM cung cấp một thiết bị block paravirtual được hỗ trợ bởi một file, logical volume hoặc dataset. Storage phía sau đó có thể nằm trên các ổ NVMe mà guest không bao giờ biết. Tên thiết bị mô tả lớp ảo hóa. Chỉ phép đo latency mới mô tả loại media.
rotational 0 có chứng minh tôi đang dùng ổ NVMe không?
Không. /sys/block/<dev>/queue/rotational chứa giá trị 0 nghĩa là kernel không xem thiết bị này có platter quay. Tuy nhiên, trong VPS, đây là một thiết lập chứ không phải phép đo. virtio-blk không có feature bit cho loại media, và Linux virtio-blk driver báo cáo 1 cho mọi disk trừ khi có thứ gì đó ghi đè. Vì vậy, 0 ở đó thường có nghĩa là ai đó đã đặt thủ công. Giá trị này không phân biệt được NVMe với SATA SSD, cũng không phân biệt được flash cục bộ với network volume. 1 trong VPS cũng không chứng minh đó là hard drive. Hãy dựa vào latency của fio, không dựa vào flag này.
Vì sao nvme list trả về bảng trống trên VPS của tôi?
Vì guest của bạn không được cung cấp NVMe controller. nvme list và lspci đều đọc các thiết bị mà virtual machine nhìn thấy. Disk virtio-blk hoặc virtio-scsi không cung cấp NVMe controller để liệt kê. Bảng trống là kết quả bình thường trên hầu hết gói VPS và không chứng minh host không có ổ NVMe. Cài nvme-cli bằng sudo apt install -y nvme-cli và dự kiến sẽ nhận bảng trống, trừ khi một controller đã được pass through.
Kết quả fio nào được xem là storage cấp NVMe?
Với queue depth 1, random read 4k và --direct=1, completion latency trung bình gần 110 microseconds là mức của NVMe, tương ứng khoảng 9,000 IOPS. Mức khoảng 320 microseconds thường chỉ SATA SSD. Mức khoảng 900 microseconds thường chỉ network attached storage, trong đó các lần đọc không trúng cache của host phải đi qua một network hop, hoặc một volume đang bị host throttling. Đây là các khoảng điển hình được công bố cho tháng 08 năm 2026. Hãy so sánh bậc độ lớn thay vì các con số chính xác, và chạy lại phép đo vào các giờ khác nhau trước khi kết luận.