هل قرص VPS لديك NVMe فعلًا؟ تحقّق من Linux
يقول مضيفك إن القرص NVMe؟ افحصه من داخل الضيف باستخدام lsblk وsysfs وnvme-cli، ثم شغّل اختبار fio محدوداً، وافهم كيف يخفي virtio القرص الحقيقي.
تحقّق من قرص NVMe على Linux في أربع خطوات
للتحقّق من قرص NVMe على Linux VPS، نفّذ أربع عمليات فحص بالترتيب: lsblk لمعرفة اسم الجهاز، والعَلَمة rotational ومسار الناقل في sysfs، وnvme list للتحقّق من وجود وحدة تحكّم NVMe فعلية، ثم نفّذ fio لفترة قصيرة للحصول على الرقم الوحيد الذي لا يستطيع المضيف تزييفه. تستغرق عمليات الفحص الثلاث الأولى ثانية واحدة لكل منها. أما العملية الأخيرة فتحسم المسألة، لأن hypervisor يخفي القرص الفعلي عن النظام الضيف في معظم منصات VPS.
NVMe (non-volatile memory express) هو البروتوكول الذي تستخدمه وحدات تخزين flash عبر مسارات PCIe (peripheral component interconnect express). وقد حلّ محل مسار SATA وAHCI المصمم للأقراص الدوارة. وتكمن سرعته في إزالة عنق زجاجة في تنظيم قوائم الانتظار بين CPU وflash. داخل آلة افتراضية، نادراً ما تتعامل مع هذا البروتوكول مباشرة. بل تتعامل مع قرص افتراضي يجهزه المضيف لك، ولذلك يصف اسم الجهاز في النظام الضيف برنامج تشغيل، لا وسيط التخزين الموجود في الخادم.
الخطوة 1: ماذا يعرض lsblk؟
يقرأ lsblk قائمة أجهزة الكتل التي يحتفظ بها kernel. يخفي الخيار -d الأقسام، لذلك ترى سطراً واحداً لكل قرص.
lsblk -d -o NAME,ROTA,SIZE,TYPE,TRAN,MODELتُظهر KVM VPS عادةً ما يلي:
NAME ROTA SIZE TYPE TRAN MODEL
vda 1 80G disk virtioتغطي أنماط التسمية الثلاثة التالية معظم خوادم Linux:
nvme0n1هي namespace رقم 1 على وحدة تحكم NVMe رقم 0. يستخدم guest جهاز NVMe حقيقياً أو محاكياً.sdaهي طبقة SCSI. تظهر أقراص SATA وSAS الحقيقية هنا، وكذلك برنامج التشغيل virtio-scsi.vdaهي virtio-blk، وهو برنامج تشغيل الكتل شبه الافتراضي الذي تستخدمه معظم مضيفات KVM افتراضياً.
يقرأ العمود TRAN (وسيلة النقل) القيمة nvme لجهاز NVMe، والقيمة sata لقرص SATA الذي يستطيع guest رؤيته مباشرةً. مع virtio-blk، تعرض الإصدارات الحالية من util-linux القيمة virtio، التي يستنتجها lsblk من اسم جهاز vd، بينما تتركها الإصدارات الأقدم فارغة. في كلتا الحالتين، لا توجد وسيلة نقل فعلية يمكن لـguest الإبلاغ عنها. يكون 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 عندما يتعامل kernel مع الجهاز على أنه يحتوي على أسطوانات دوّارة، وعلى 0 خلاف ذلك. في الخوادم الفعلية، تأتي القيمة من محرك الأقراص. أما مع virtio-blk، فلا تأتي من أي مكان، لأن مواصفة virtio-blk لا تتضمن بت ميزة يحدد نوع الوسائط أو سرعة الدوران، ولأن برنامج تشغيل virtio-blk في Linux يضع علامة الدوران على كل قرص. لذلك يقرأ vda عادةً القيمة 1 حتى على مضيف يستخدم وحدات تخزين فلاش بالكامل، ما لم يفرض أحد القيمة 0 باستخدام قاعدة udev. أما في جهاز sda الذي يستخدم virtio-scsi، فتكون القيمة هي ما اختار المضيف إعداده. لذلك لا يستطيع هذا العلم داخل 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، لكنها مأخوذة من kernel بدلاً من عمود منسّق، وهو أمر مفيد عندما يكون الحقل 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 صفاً واحداً لكل مساحة أسماء، ويتضمن الرقم التسلسلي لوحدة التحكم، وسلسلة الطراز، ومراجعة البرنامج الثابت. يعني الجدول الفارغ عدم إتاحة أي جهاز NVMe للآلة الضيفة. ويعني عدم طباعة lspci لأي سطر مطابق الشيء نفسه من الجانب الآخر: لا يحتوي ناقل PCI الافتراضي الذي تستطيع الآلة الضيفة رؤيته على وحدة تحكم NVMe. هاتان النتيجتان الفارغتان هما النتيجة المعتادة على VPS يستخدم virtio، ولا تشكّل أي منهما دليلاً على عدم احتواء المضيف على أقراص NVMe.
إذا ظهرت مساحة أسماء، فإن nvme-cli يقدّم معلومات إضافية. يطبع sudo nvme id-ctrl /dev/nvme0 هوية وحدة التحكم، بينما يطبع sudo nvme smart-log /dev/nvme0n1 درجة الحرارة، وساعات التشغيل منذ تشغيل الطاقة، والنسبة المئوية من قدرة التحمل المقدّرة للكتابة التي استُخدمت. شغّل هذين الأمرين فقط عندما يسرد nvme list جهازاً فعلياً، لأن كلا الأمرين يحتاج إلى فتح عقدة /dev/nvme* حقيقية.
لماذا يعرض خادم NVMe فعلياً /dev/vda
يحدّد برنامج Hypervisor نموذج الجهاز الذي يراه الضيف، ولا يعتمد هذا الاختيار على وسيط التخزين الأساسي. توجد 3 ترتيبات شائعة.
- استخدام virtio-blk أو virtio-scsi فوق ملف، أو وحدة تخزين منطقية، أو مجموعة بيانات ZFS موجودة على محركات NVMe. سترى
vdaأوsda. التخزين من نوع NVMe، لكن لا يمكن للضيف معرفة ذلك. - استخدام وحدة تحكم NVMe محاكاة أمام أي نوع من التخزين. سترى
nvme0n1حتى عندما تُخزَّن البيانات على مصفوفة SATA أو على وحدة تخزين شبكية تبعد رفَّين. - استخدام PCIe passthrough، حيث يمرّر المضيف وحدة تحكم فعلية إلى ضيف واحد. سترى
nvme0n1حقيقياً مع سلسلة طراز فعلية. هذا نادر في خطط VPS المشتركة، لأن البطاقة تصبح مخصصة لذلك العميل وحده.
لذلك قد يضللك اسم الجهاز في كلا الاتجاهين. والأسوأ أن المضيف قد يضع ذاكرة تخزين مؤقتة من نوع write-back، أو طبقة RAID، أو وحدة تخزين شبكية مكررة بين عمليات الكتابة التي تجريها ووحدات الفلاش. يغيّر كل عنصر من هذه العناصر الأداء الذي تحصل عليه من دون تغيير أي اسم في /sys. لهذا السبب يبدأ الفحص من الاسم، لكنه لا ينتهي عنده. إذا كنت لا تزال تختار خطة، توضّح الفروق بين تخزين NVMe وتخزين SATA SSD ما الذي تستحق كل فئة أن تدفع مقابله فعلياً.
الاختبار الصادق هو زمن الاستجابة، لذا قِسه
يُجري fio (أداة اختبار الإدخال والإخراج المرنة) عمليات قراءة فعلية من ملف فعلي، ويعرض المدة التي استغرقتها كل عملية. تُعد عمليات القراءة العشوائية الصغيرة عبء العمل المناسب هنا، لأنها تكشف زمن الرحلة ذهاباً وإياباً إلى وسيط التخزين، ولا يمكن لخدمة القراءة المسبقة تلبية هذه العمليات.
أنشئ ملف الاختبار أولاً، وتحقق من أن نظام الملفات هذا يقبل الإدخال والإخراج غير المخزَّنين مؤقتاً. يفتح --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، ومدة عشرين ثانية، و256 MB من البيانات. لن يملأ ذلك القرص، ولن يؤدي إلى تصنيفك على أنك تسيء الاستخدام. كما أن عمق قائمة الانتظار 1 هو الإعداد الصادق لهذا السؤال، لأن قوائم الانتظار العميقة تتيح لجهاز بطيء الاختباء خلف المعالجة المتوازية، بينما يظل زمن الاستجابة مرتفعاً.
قراءة مخرجات fio
هناك سطران مهمان. يبدو سطر الملخص على النحو التالي: read: IOPS=9012, BW=35.2MiB/s، ويطبع fio تحته كتلة clat. تمثل clat زمن استجابة الإكمال: أي المدة بين إرسال fio لطلب قراءة وتسليم النواة للبيانات. اقرأ قيمة avg، ثم اقرأ النسبة المئوية 99.00th في قائمة clat percentiles. يوضح المتوسط فئة التخزين. وتوضح النسبة المئوية 99 مدى بطء أبطأ 1 بالمئة من عمليات القراءة، وهو الموضع الذي يظهر فيه عادةً تأثير التنافس على خادم مشترك أولاً.
يطبع fio زمن الاستجابة بالميكروثانية عندما تكون القيم صغيرة، وينتقل إلى الملليثانية عندما لا تكون كذلك. تحقق من الوحدة في السطر قبل إجراء أي مقارنة.
ما الأرقام التي تميّز فئة NVMe عن فئة SATA
القيم أدناه هي قيم منشورة نموذجية لقراءات عشوائية بحجم 4k لمهمة واحدة عند عمق قائمة انتظار يساوي 1، وقد جُمعت من وثائق المورّدين والمعايير المرجعية التي ينشرها المجتمع حتى August 2026. وهي نطاقات للمقارنة، وليست قياسات من خادمك.
البيانات وراء هذا الرسم البياني
[
{
"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 خلال نحو 110 ميكروثانية، وتصل إلى نحو 9,000 IOPS عند عمق قائمة انتظار يساوي 1. أما SSD محلي من نوع SATA، فيسجّل نحو 320 ميكروثانية و3,100 IOPS. وتبلغ وحدة التخزين الكتلية المتصلة عبر الشبكة نحو 900 ميكروثانية و1,100 IOPS، لأن القراءة التي لا تجد البيانات في أي ذاكرة تخزين مؤقت على المضيف يجب أن تعبر الشبكة قبل أن تصل إلى ذاكرة الفلاش.
عند عمق قائمة انتظار يساوي 1، يكون العمودان متقاربين جداً، لأنهما يعبّران عن الحقيقة نفسها بصيغتين مختلفتين: عندما تكون قراءة واحدة فقط قيد التنفيذ في كل مرة، يساوي معدل النقل تقريباً واحداً مقسوماً على زمن الاستجابة، وينخفض قليلاً بعد احتساب الحمل الإضافي لكل طلب. إذا كان متوسطك أقرب إلى 110 منه إلى 320 ميكروثانية، فأنت تستخدم وحدة تخزين من فئة NVMe، أياً كان ما قرر lsblk أن يسمّي الجهاز. وإذا كان أقرب إلى 900 ميكروثانية، فإما أن هناك مكوّناً أبطأ من وحدة فلاش محلية في المسار، أو أن المضيف يفرض حداً على IOPS الخاصة بوحدتك، وهو أمر يمكن لبرامج مراقبة الأجهزة الافتراضية مثل QEMU فرضه أياً كانت وحدة التخزين الموجودة في الأسفل. في كلتا الحالتين، لا تحقق وحدتك زمن استجابة من فئة NVMe، بغض النظر عما تقوله صفحة الطلب عن محركات أقراص المضيف.
شغّل الاختبار أكثر من مرة قبل تقديم شكوى
الاختبار الواحد عينة، وليس نتيجة. يشترك VPS في أقراصه مع عملاء آخرين، لذلك قد يضاعف جار نشط زمن الاستجابة لمدة عشر دقائق ثم يختفي تأثيره. تمنح بعض المنصات أيضاً أرصدة burst، ما يجعل الدقائق الأولى من أي اختبار تبدو ممتازة. شغّل الأمر نفسه ثلاث أو أربع مرات في ساعات مختلفة من اليوم، وقارن أسوأ نتيجة لا أفضل نتيجة. النتيجة السيئة الواحدة حالة عابرة. أما النمط المتكرر فهو خلل يستحق فتح تذكرة دعم، وستكون التذكرة أكثر فاعلية عند إرفاق ثلاثة مخرجات مؤرخة من fio. وللحصول على صورة أشمل تشمل CPU والشبكة إضافة إلى القرص، يستخدم اختبار VPS شامل الانضباط نفسه مع الأنظمة الفرعية الأخرى.
ماذا تفعل بالنتيجة
إذا كان زمن الاستجابة ضمن نطاق NVMe، فتوقف عن القلق بشأن اسم الجهاز وانتقل إلى الخطوة التالية. vda ليس تراجعاً في الأداء. فهو أسرع برنامج تشغيل للقرص الافتراضي توفره معظم المضيفات، وهو الخيار المطلوب هنا.
إذا كان زمن الاستجابة ضمن نطاق التخزين الشبكي، مع أن الخطة تُباع على أنها NVMe محلي، فلديك ادعاء محدد وقابل لإعادة الإنتاج: أمر fio الدقيق، ومتوسط زمن إكمال العمليات، والأوقات التي شغّلت فيها الاختبار. هذه حالة مناسبة لفتح تذكرة دعم، وليست جدالاً في المنتدى. قبل إرسالها، تأكد من أن القرص ليس ممتلئاً أو شديد التجزئة، وتأكد من عدم وجود عملية على الخادم تكتب بكثافة أثناء الاختبار.
شغّل هذا الفحص في يوم تهيئة الخادم، لا في اليوم الذي تشعر فيه بأن شيئاً ما أصبح بطيئاً، حتى يتوفر لديك خط أساس تقارن به لاحقاً. ويناسب ذلك طبيعياً الدقائق العشر الأولى على VPS جديد، إلى جانب إعداد جدار الحماية ومفاتيح SSH. إذا كان الفرق بين مستويات التخزين لا يزال غير واضح، فتشرح ما الذي يوفّره VPS مزود بقرص SSD فعلياً الأساس الذي يعتمد عليه هذا الموضوع.
FAQ
لماذا يعرض lsblk /dev/vda بينما يعلن مضيفي عن NVMe؟
لأن 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، ولا بين وحدة تخزين فلاش محلية ووحدة تخزين شبكية. كما أن قيمة 1 داخل VPS لا تثبت وجود قرص صلب، لذلك اعتمد على زمن استجابة fio، لا على هذا العلم.
لماذا يكون ناتج nvme list فارغاً على VPS لدي؟
لأنه لا توجد وحدة تحكم NVMe مكشوفة لنظام الضيف لديك. يقرأ كل من nvme list وlspci ما يمكن للآلة الافتراضية رؤيته، ولا يقدّم قرص virtio-blk أو virtio-scsi وحدة تحكم NVMe لتعدادها. يكون الجدول الفارغ هو النتيجة الطبيعية في معظم خطط VPS، ولا يثبت أن المضيف يفتقر إلى محركات NVMe. ثبّت nvme-cli باستخدام sudo apt install -y nvme-cli، وتوقع أن يبقى الجدول فارغاً ما لم تُمرَّر وحدة تحكم إلى الضيف.
ما نتيجة fio التي تُعد تخزيناً من فئة NVMe؟
عند عمق قائمة انتظار قدره 1، ومع عمليات قراءة عشوائية بحجم 4k و--direct=1، يُعد متوسط زمن إكمال قريباً من 110 ميكروثانية من فئة NVMe، وينتج عنه نحو 9,000 من عمليات الإدخال والإخراج في الثانية. وتشير قيمة تقارب 320 ميكروثانية إلى SATA SSD، بينما تشير قيمة تقارب 900 ميكروثانية إلى تخزين متصل بالشبكة، حيث تعبر القراءات التي لا تصيب ذاكرة التخزين المؤقت للمضيف قفزة شبكية، أو إلى وحدة تخزين يفرض المضيف حداً لأدائها. هذه نطاقات نموذجية منشورة لشهر August 2026، لذلك قارن رتب الحجم بدلاً من مقارنة الأرقام الدقيقة، وكرّر الاختبار في ساعات مختلفة قبل استخلاص نتيجة.