تفاوت NVMe و SSD در سرور مجازی (VPS) چیست؟
آیا NVMe روی VPS واقعاً سرعت را افزایش میدهد؟ در این مقاله بررسی میکنیم که چرا هایپروایزر و همسایگان سرور مهمتر از نوع دیسک هستند. با دستور fio عملکرد دیسک خود را بسنجید.
آیا NVMe روی یک VPS اهمیت دارد؟
استفاده از NVMe روی یک VPS زمانی اهمیت پیدا میکند که نرمافزار شما تعداد زیادی عملیات خواندن و نوشتن کوچک انجام میدهد و منتظر پایان یافتن تکتک آنها میماند. این موضوع برای سایتی که صفحات کششده را ارائه میدهد یا برنامهای که بیشتر زمان خود را در انتظار شبکه سپری میکند، تفاوت چندانی ایجاد نمیکند. نوع رسانه ذخیرهسازی تنها یک عامل است. هایپرویزوری که بین سیستمعامل شما و دیسک قرار دارد و سایر مهمانانی (guests) که از همان میزبان (host) استفاده میکنند، سقف عملکردی که واقعاً دریافت میکنید را تعیین میکنند.
تغییرات NVMe و آنچه تغییر نمیکند
NVMe (مخفف non-volatile memory express) نوعی حافظه فلش نیست. این یک پروتکل و رابط اتصال برای دسترسی به حافظه فلش است. یک دستگاه NVMe روی مسیرهای PCIe (مخفف peripheral component interconnect express) قرار میگیرد و با پروتکل NVMe ارتباط برقرار میکند. یک SSD از نوع SATA (مخفف serial ATA) روی یک لینک SATA قرار دارد و از پروتکل AHCI (مخفف advanced host controller interface) استفاده میکند. تراشههای حافظهای که دادههای شما را نگه میدارند، ممکن است در هر دو مورد کاملاً یکسان باشند.
دو تفاوت اصلی وجود دارد که هر دو مربوط به مسیر ارسال دستورات هستند، نه خودِ فضای ذخیرهسازی.
صفها (Queues). پروتکل AHCI به هسته سیستمعامل یک صف دستور میدهد که ظرفیت آن 32 دستور است. NVMe اجازه میدهد هزاران صف داشته باشید؛ در عمل، یک صف برای هر هسته CPU که هر کدام بسیار عمیقتر از 32 دستور هستند. فرآیندی که در هر لحظه فقط یک بلوک را میخواند، متوجه این تفاوت نمیشود. اما یک پایگاه داده با 64 درخواست خواندنِ معلق، تفاوت را حس میکند: در SATA، درخواست سیوسوم باید منتظر خالی شدن جایگاه در صف بماند تا دستگاه حتی آن را ببیند، در حالی که دستگاه NVMe همه آنها را میپذیرد و بهطور همزمان پردازش میکند.
پهنای لینک (Link width). یک لینک SATA III با سرعت 6 گیگابیت بر ثانیه کار میکند که پس از کسر سربار پروتکل، حدود 550 مگابایت بر ثانیه داده واقعی منتقل میکند. این یک سقف ثابت است، صرفنظر از اینکه چه نوع حافظه فلشی پشت آن باشد. چهار مسیر PCIe چندین گیگابایت بر ثانیه را منتقل میکنند، بنابراین لینک دیگر گلوگاه نخواهد بود.
در مورد تأخیر (Latency)، انتظارات معمولاً اشتباه است. در عمق صف 1، یعنی زمانی که تنها یک درخواست در حال اجراست، یک SSD از نوع SATA یک خواندن 4k را در حدود 100 تا 150 میکروثانیه پاسخ میدهد. NVMe این کار را در حدود 80 تا 100 میکروثانیه انجام میدهد. هر دو سریع هستند و هیچ برنامهای در یک درخواست واحد متوجه این تفاوت نمیشود. شکاف عملکرد در شرایط همزمانی (Concurrency) ایجاد میشود. عمق صف، یعنی تعداد درخواستهایی که همزمان در حال اجرا هستند، تنظیمی است که تعیین میکند آیا این دو رسانه مشابه به نظر میرسند یا بسیار متفاوت.
ذخیرهسازی بلوکی شبکه (Network block storage) کلاس سومی است که فیزیک متفاوتی دارد. یک عملیات نوشتن از شبکه عبور کرده و به یک کلاستر ذخیرهسازی میرسد و تنها زمانی تأیید میشود که کلاستر آن را دریافت کرده باشد؛ بنابراین تأخیر آن به جای میکروثانیه، با میلیثانیه اندازهگیری میشود. آنچه در ازای این تأخیر به دست میآورید، پایداری (Durability) است: حجم ذخیرهسازی از میزبانی که به آن متصل است عمر طولانیتری دارد و میتوان از آن snapshot گرفت یا اندازه آن را تغییر داد.
ارقام معمول منتشرشده: NVMe، SATA SSD و فضای ذخیرهسازی شبکه
The data behind this chart
[
{
"disk": "Local NVMe SSD",
"iops_4k_read": "184,000",
"p99_latency_ms": 0.4,
"seq_read_mbps": "3,400"
},
{
"disk": "Local SATA SSD",
"iops_4k_read": "90,000",
"p99_latency_ms": 1.2,
"seq_read_mbps": "550"
},
{
"disk": "Network block storage",
"iops_4k_read": "12,500",
"p99_latency_ms": 6.5,
"seq_read_mbps": "250"
}
]یک دستگاه NVMe محلی معمولاً با 184,000 عملیات خواندن تصادفی 4k در ثانیه (IOPS) در عمق صف 32 گزارش میشود. همین تست روی یک SATA SSD به دلیل محدودیت صف AHCI و لینک 6 Gbit/s، نزدیک به 90,000 گزارش میشود. فضای ذخیرهسازی بلوکی شبکه معمولاً توسط ارائهدهنده محدود میشود تا سختافزار، و 12,500 یک سقف مستند رایج برای آن است.
تأخیر (Latency) همین موضوع را با واحدی که کاربران شما حس میکنند بیان میکند. تأخیر خواندن p99، یعنی کندترین 1 درصد درخواستها، در NVMe محلی حدود 0.4 میلیثانیه و در SATA حدود 1.2 میلیثانیه است. با قرار دادن شبکه در مسیر، این مقدار به 6.5 میلیثانیه میرسد که بیش از ده برابر رقم NVMe است.
خواندن ترتیبی (Sequential) بیشترین شکاف و کمترین کاربرد را دارد: 3,400 مگابایت بر ثانیه در مقابل 550 مگابایت بر ثانیه. تقریباً هیچ سرویسی در سرور وجود ندارد که یک فایل بزرگ را از ابتدا تا انتها با حداکثر سرعت بخواند. ستونهای تصادفی و تأخیر، عملکرد واقعی یک پایگاه داده، صف ایمیل یا مدیر بسته (package manager) را توصیف میکنند.
این ارقام از کجا میآیند و چرا ارقام شما متفاوت خواهد بود
تعداد 3 ردیف موجود، ارقام دیتاشیت سازنده برای دستگاههای محلی و محدودیتهای مستند هر حجم برای فضای ذخیرهسازی شبکه هستند که تا ژوئیه 2026 بهروزرسانی و گرد شدهاند. این ارقام فرض را بر اندازه بلوک 4k، خواندن تصادفی، عمق صف 32 و یک job واحد میگذارند که همان الگوی تست منتشرشده توسط سازندگان است. VPS شما یک مهمان روی یک میزبان اشتراکی است، بنابراین همان تست روی سیستم شما معمولاً نتیجه کمتری میدهد و بین اجراهای مختلف متغیر است. این ردیفها را به عنوان الگوی تفاوت بین این سه کلاس در نظر بگیرید، نه به عنوان هدفی که باید به آن دست یابید.
کدام بار کاری دیسک را حس میکند
یک قاعده کلی برای همه آنها وجود دارد: بار کاری تنها زمانی دیسک را حس میکند که منتظر آن بماند. لینوکس دادههای فایلهایی که اخیراً استفاده شدهاند را در RAM و در page cache نگه میدارد، بنابراین خواندن دوم یک فایل هرگز به حافظه جانبی نمیرسد. اگر مجموعه کاری (working set)، یعنی دادههایی که واقعاً در حال استفاده هستند، در RAM جا شود، عملیات خواندن پس از اولین بار، به خواندن از حافظه تبدیل میشود. عملیات نوشتن متفاوت است. هر نوشتنی که برنامه با fsync() آن را flush میکند، باید پیش از آنکه به برنامه اجازه ادامه کار داده شود، روی حافظه پایدار (stable storage) قرار گرفته باشد.
کارهایی که commit میکنند. دیتابیسهای PostgreSQL، MySQL و SQLite در هنگام commit، دستور fsync() یا fdatasync() را فراخوانی میکنند و هر commit منتظر پاسخ دستگاه میماند. بنابراین نرخ commit یک اتصال، توسط تأخیر نوشتن (write latency) تعیین میشود، نه پهنای باند. دستگاهی که در 0.2 میلیثانیه flush را انجام میدهد، اجازه commit بسیار بیشتری در ثانیه نسبت به دستگاهی با تأخیر 5 میلیثانیه میدهد و هیچ مقدار throughput این موضوع را تغییر نمیدهد. MySQL در صورت عقب ماندن flush، این موضوع را در لاگ خطا گزارش میکند:
[Note] InnoDB: page_cleaner: 1000ms intended loop took 4589ms. The settings might not be optimal.دیتابیس PostgreSQL این مورد را در خطوط checkpoint خود گزارش میدهد، جایی که مقدار بزرگ sync= به معنای کند بودن خودِ عملیات flush است:
LOG: checkpoint complete: wrote 8192 buffers (25.0%); write=27.694 s, sync=11.207 s, total=39.001 sکارهایی که با فایلهای کوچک زیادی سروکار دارند. هر فایل شامل عملیات متادیتا است که یک خواندن ترتیبی (sequential) بزرگ آن را ندارد. دستورات npm install، git clone یک مخزن بزرگ، استخراج تصاویر کانتینر، یک Maildir برای ذخیره ایمیل و تهیه نسخه پشتیبان که در یک درخت فایل بزرگ پیمایش میکند، همگی زمان خود را صرف دسترسی تصادفی (random access) به فایلهای کوچک میکنند. یک job پشتیبانگیری restic روی یک VPS هر فایلی را که قبلاً ندیده است میخواند و هش میکند، بنابراین زمان واقعی (wall-clock time) برای پشتیبانگیری از یک میلیون فایل، دقیقاً با تأخیر خواندن تصادفی همبستگی دارد. همین موضوع در مورد du -sh نیز صادق است که فقط متادیتا را میخواند و نه چیز دیگری.
دیتابیسهایی که حجم آنها از RAM بیشتر میشود نیز در این دسته قرار میگیرند. زمانی که ایندکس دیگر در page cache جا نمیشود، هر جستجو به یک خواندن تصادفی تبدیل شده و دیسک دوباره به گلوگاه (critical path) بازمیگردد.
چه بارهایی (workloads) متوجه نوع دیسک نمیشوند
یک وبلاگ یا سایت شرکتی کوچک. صفحات کوچک هستند، پس از اولین درخواست، تمام آنها در page cache قرار میگیرند و محدودیت اصلی، CPU برای رندر کردن یا پهنای باند برای داراییها (assets) است. یک LAMP stack on Ubuntu 24.04 که یک سایت با ترافیک پایین را میزبانی میکند، پس از گرم شدن (warm شدن)، تقریباً هیچ IO دیسکی ندارد.
استریم رسانه. یک استریم 4K با سرعت 40 Mbit/s، معادل 5 MB/s خواندن انجام میدهد. ده استریم همزمان 50 MB/s میخوانند که حتی فضای ذخیرهسازی بلوکی شبکه (network block storage) نیز بدون مشکل آن را تأمین میکند. یک A Jellyfin media server on a VPS توسط سهمیه خروجی شبکه (egress) و هنگام transcoding توسط CPU محدود میشود، نه توسط رسانه ذخیرهسازی.
استنتاج مدل محلی (Local model inference). Running Ollama on a VPS to self-host an LLM فایل مدل را یک بار میخواند و سپس در RAM کار میکند. NVMe زمان بارگذاری یک مدل 20 GB را از چند دقیقه به چند ثانیه کاهش میدهد. این کار تأثیری بر تعداد توکن در ثانیه ندارد، چرا که آن محدود به پهنای باند حافظه و CPU است.
هر پردازشی که منتظر یک سرویس خارجی است. یک worker که برای هر کار 800 ms صرف درخواست HTTP میکند، با دیسک بهتر سریعتر نخواهد شد.
چرا هایپروایزر به اندازه رسانه ذخیرهسازی اهمیت دارد
شما هرگز مستقیماً با دستگاه ارتباط برقرار نمیکنید. شما با یک دیسک مجازی که هایپروایزر ارائه میدهد (معمولاً از طریق virtio) در تعامل هستید و چندین تصمیم در این لایه، اهمیت بسیار بیشتری نسبت به تفاوت NVMe با SATA دارند.
شما نمیتوانید رسانه فیزیکی را از داخل سیستمعامل مهمان مشاهده کنید. دستور lsblk -d -o NAME,ROTA,SIZE,MODEL خروجی vda را با یک مدل خالی نشان میدهد، زیرا virtio هویت واقعی درایو را عبور نمیدهد. دستور cat /sys/block/vda/queue/rotational آنچه را که هایپروایزر تبلیغ میکند گزارش میدهد، بنابراین عدد 0 در آنجا مدرکی برای فلش بودن دیسک نیست. دستور nvme list از بسته nvme-cli، در اکثر VPSها هیچ چیزی را فهرست نمیکند، حتی اگر میزبان پر از درایوهای NVMe باشد؛ زیرا دیسک شما یک دستگاه virtio است و نه یک دستگاه NVMe. طرحی که ادعای NVMe دارد، معمولاً توصیفکننده سختافزار میزبان است. حجم ذخیرهسازی شما ممکن است همچنان از طریق شبکه متصل باشد.
حالت کش میزبان (Host cache mode) بیش از خودِ رسانه بر اعداد تأثیر میگذارد. با فعال بودن writeback caching روی میزبان، یک عملیات fsync() در سیستمعامل مهمان میتواند به محض اینکه میزبان دادهها را در RAM خود دریافت کرد، پایان یابد. این کار نتیجه بنچمارکی را تولید میکند که هیچ دستگاه فیزیکی قادر به ارائه آن نیست. همچنین این بدان معناست که در صورت کرش کردن میزبان، ممکن است دادههایی که دیتابیس شما تصور میکند با موفقیت نوشته شدهاند، از دست بروند. با حالت کش none، اعداد پایینتر و واقعیتر هستند.
محدودیتها و اعتبار burst. بسیاری از ارائهدهندگان، IOPS را برای هر حجم یا هر طرح محدود میکنند و بسیاری از حجمهای تحت شبکه از یک سهمیه burst استفاده میکنند. سهمیه burst مجموعهای از اعتبارهاست: حجم تا زمانی که اعتبار دارید سریع عمل میکند و سپس به یک سطح پایه بسیار پایینتر سقوط میکند. تشخیص این نشانه آسان است. یک عملیات import یا restore برای چند دقیقه سریع اجرا میشود، سپس بهشدت کند شده و همانطور کند باقی میماند، بدون اینکه تغییری در پیکربندی شما ایجاد شده باشد. شما اعتبار خود را مصرف کردهاید.
همسایهها. روی یک میزبان اشتراکی، تأخیر دیسک شما با فعالیت سایر مهمانها تغییر میکند. به همین دلیل است که باید بیش از یک بار اندازهگیری کنید. همان تست را صبح و دوباره عصر اجرا کنید و تفاوت آنها را مقایسه کنید. روی یک میزبان شلوغ، تفاوت بین دو اجرا روی یک حجم واحد، اغلب بزرگتر از تفاوت اعلامشده بین دو رسانه ذخیرهسازی مختلف است.
نحوه اندازهگیری فضای دیسک واقعی در VPS
ابزار fio را که استاندارد بنچمارک IO است نصب کرده و اندازهگیری را انجام دهید. ابتدا سه نکته را در نظر داشته باشید. این تست یک فایل ایجاد میکند، بنابراین از فضای دیسک استفاده کرده و در سهمیه IOPS که برای آن هزینه پرداخت میکنید محاسبه میشود. مدت زمان اجرا را کوتاه نگه دارید. آن را با عمق صف (queue depth) کامل روی درایوی که در حال سرویسدهی به ترافیک زنده است اجرا نکنید، زیرا با برنامه خودتان رقابت خواهید کرد.
sudo apt update && sudo apt install -y fio ioping sysstat
cd /var/tmpخواندن تصادفی (Random read) با عمق صف 32، که همان عمقی است که فروشندگان اعلام میکنند:
fio --name=randread --filename=fio.test --size=1G --bs=4k --rw=randread \
--ioengine=libaio --direct=1 --iodepth=32 --numjobs=1 \
--runtime=30 --time_based --group_reportingخطی که اهمیت دارد با read: شروع میشود.
read: IOPS=184k, BW=719MiB/s (754MB/s)(21.1GiB/30001msec)گزینه --direct=1 باعث دور زدن کش صفحه (page cache) سیستمعامل مهمان میشود، بنابراین نتیجه، دستگاه ذخیرهسازی را توصیف میکند نه حافظه RAM شما را. اگر آن را حذف کنید، حافظه را اندازهگیری خواهید کرد که عددی را برمیگرداند که هیچ دیسکی به آن نمیرسد. اگر فضا دارید از --size=4G یا بزرگتر استفاده کنید، زیرا یک فایل 1G میتواند کاملاً در کش میزبان (host) قرار بگیرد و نتیجه را بهطور غیرواقعی بهبود بخشد.
عمق صف 1، تأخیر (latency) خام را نشان میدهد که همان چیزی است که یک پردازش تکرشتهای تجربه میکند:
fio --name=lat --filename=fio.test --size=1G --bs=4k --rw=randread \
--ioengine=libaio --direct=1 --iodepth=1 --runtime=30 --time_basedتست commit رفتار پایگاه داده را پیشبینی میکند. این تست 4k مینویسد و پس از هر نوشتن fdatasync() را فراخوانی میکند، بنابراین نرخ گزارششده شامل عملیات flush نیز میشود:
fio --name=commit --filename=fio.test --size=1G --bs=4k --rw=randwrite \
--ioengine=psync --fdatasync=1 --runtime=30 --time_based
rm -f fio.testعدد IOPS حاصل از این اجرا به بالاترین تعداد تراکنشهای کوچک در ثانیهای که یک اتصال پایگاه داده میتواند commit کند نزدیک است، زیرا یک commit منتظر همان عملیات flush میماند.
برای یک نمونهگیری سریع بدون استفاده از fio:
ioping -c 20 .--- . (ext4 /dev/vda1) ioping statistics ---
19 requests completed in 4.13 ms, 76 KiB read, 4.60 k iops, 17.9 MiB/s
min/avg/max/mdev = 174.2 us / 217.6 us / 386.1 us / 51.3 usمقدار mdev، یعنی انحراف میانگین، به اندازه خود میانگین ارزشمند است. انحراف زیاد در یک سرور بدون بار، به این معنی است که زیرساخت ذخیرهسازی اشتراکی است و در حال حاضر مشغول میباشد.
نحوه خواندن نتایج
از ژوئیه 2026، این مقادیر برای یک VPS کوچک معقول هستند. دهها هزار IOPS خواندن تصادفی 4k در عمق صف 32، با تأخیر کمتر از حدود 0.3 میلیثانیه در عمق صف 1، با حافظه فلش محلی سازگار است. تأخیر چند میلیثانیهای در عمق صف 1، صرفنظر از نام پلن، نشاندهنده وجود یک مسیر شبکه است. خواندنهای ترتیبی که در نزدیکی 550 MB/s متوقف میشوند، مشخصه یک لینک SATA هستند. عددی که بسیار بالاتر از توانایی هر دستگاه واحد باشد، به این معنی است که کشینگ در مسیر قرار دارد که تقریباً همیشه در سطح میزبان (host) رخ میدهد.
برای مشاهده تأثیر بار کاری فعلی (live workload) بر دیسک:
iostat -x 1 3
vmstat 1 5
cat /proc/pressure/ioدر خروجی iostat -x، مقادیر r_await و w_await را بخوانید که میانگین میلیثانیههای انتظار یک درخواست است، و همچنین aqu-sz که میانگین طول صف است. در یک دیسک مجازی، %util را نادیده بگیرید. این مقدار سهم زمانی را گزارش میکند که حداقل یک درخواست در انتظار بوده است؛ این شاخص در دستگاهی که همزمان به درخواستهای زیادی پاسخ میدهد، چیزی درباره اشباع (saturation) نمیگوید. بنابراین، یک %util برابر با 100 در کنار یک r_await برابر با 0.2 میلیثانیه، نشاندهنده یک دیسک فعال و سالم است. در vmstat، ستون wa درصد زمان CPU صرفشده در انتظار IO را نشان میدهد. اگر /proc/pressure/io در هسته (kernel) شما وجود دارد، مقدار some avg10= آن نشاندهنده سهم 10 ثانیه اخیر است که در آن حداقل یک تسک به دلیل IO متوقف (stalled) بوده است؛ این مستقیمترین پاسخ به این پرسش است که آیا فضای ذخیرهسازی گلوگاه (bottleneck) شماست یا خیر.
نشانههای یک VPS با محدودیت دیسک
بالا بودن load average در حالی که CPU بیکار است و مقدار زیادی wa در vmstat وجود دارد، به این معناست که پردازشها در صف انتظار دیسک قرار گرفتهاند. واضحترین سیگنال هسته (kernel)، مشاهده این پیام در dmesg -T است:
INFO: task jbd2/vda1-8:194 blocked for more than 120 seconds.این خط به این دلیل ظاهر میشود که یک thread هسته بیش از 2 دقیقه برای پاسخگویی فضای ذخیرهسازی منتظر مانده و در نتیجه، watchdog وظایف معلق (hung task) آن را ثبت کرده است. jbd2 همان thread ژورنال ext4 است؛ این یعنی کل فایلسیستم در انتظار بوده، نه فقط یک برنامه با رفتار نامناسب. در یک VPS، این وضعیت معمولاً به backend ذخیرهسازی یا اتمام سهمیه IOPS اشاره دارد.
علائم برنامه نیز از همین الگو پیروی میکنند. زمان پاسخگویی میانه (median) در حد قابلقبول باقی میماند، اما کندترین درخواستها با تأخیر طولانی مواجه میشوند، زیرا فقط درخواستهایی که با دیسک درگیر میشوند، هزینه این انتظار را میپردازند. apt upgrade برای دقایقی در وضعیت Unpacking باقی میماند، زیرا dpkg هنگام نوشتن، دادهها را flush میکند. اجرای git status در یک مخزن بزرگ، ثانیهها طول میکشد. اینها هزینههای مربوط به metadata و flush هستند، بنابراین افزایش پهنای باند کمکی به حل مشکل نخواهد کرد.
وقتی محدودیت دیسک دارید چه باید کرد
پیش از خرید IOPS، رم بخرید. اگر مجموعه دادههای فعال در page cache جا شوند، عملیات خواندن دیگر به دیسک نمیرسد. دو برابر کردن حافظه معمولاً از انتقال به یک کلاس ذخیرهسازی سریعتر بهتر عمل میکند و هزینه کمتری هم دارد.
در صورت امکان، تعداد flushها را کاهش دهید. در PostgreSQL، تنظیم synchronous_commit = off اجازه میدهد commit پیش از آنکه داده روی دیسک نوشته شود، بازگردانده شود. اگر سرور از کار بیفتد، ممکن است کسری از ثانیه از تراکنشهای آخر را از دست بدهید. دیتابیس دچار خرابی نمیشود، زیرا write-ahead log همچنان به ترتیب نوشته میشود. این معامله برای یک نسخه تحلیلی مناسب است، اما برای تراکنشهای مالی اشتباه است. تنظیم innodb_flush_log_at_trx_commit = 2 در MySQL نیز همین معامله را انجام میدهد.
فایلهای کوچک را دستهبندی کنید. انتقال یا پشتیبانگیری از یک میلیون فایل کوچک تحت تأثیر هزینه هر فایل قرار میگیرد؛ بنابراین آرشیو کردن پیش از انتقال و جابهجایی یک جریان داده (stream)، در ذخیرهسازیهای با تأخیر بالا، بسیار سریعتر از کپی کردن فایل به فایلِ ساختار درختی است.
قابلیت discard را در حجمهای thin provisioned فعال نگه دارید. در ذخیرهسازیهای thin provisioned، سیستم پشتیبان تا زمانی که فایلسیستم اعلام نکند، نمیداند که یک بلاک آزاد است. حجمی که هرگز trim نشود، بهمرور کارایی نوشتن خود را از دست میدهد. اوبونتو یک تایمر هفتگی برای این کار دارد:
systemctl status fstrim.timer
sudo fstrim -avدستور fstrim -av تعداد بایتهای trim شده به ازای هر mount point را چاپ میکند. پیامی مبنی بر اینکه عملیات discard پشتیبانی نمیشود، به این معناست که دیسک مجازی، دستور discard را به میزبان (host) منتقل نمیکند؛ بنابراین چیزی برای اصلاح توسط شما وجود ندارد.
از تنظیم IO scheduler صرفنظر کنید. روی یک دیسک virtio، دستور cat /sys/block/vda/queue/scheduler معمولاً مقدار none را نشان میدهد و زمانبندی واقعی روی میزبان انجام میشود که شما به آن دسترسی ندارید. از noatime نیز صرفنظر کنید: اوبونتو بهصورت پیشفرض با relatime mount میکند که تقریباً از تمام عملیات نوشتن atime جلوگیری میکند.
انتخاب طرح
زمانی که یک دیتابیس، سرور ایمیل، CI runner یا یک build سنگین وابسته به پکیجها روی سرور قرار دارد، هزینه NVMe را پرداخت کنید. برای یک وبسایت کششده یا برنامهای که زمان آن صرف فراخوانیهای خارجی میشود، هزینه اضافی نپردازید. اگر مطمئن نیستید، احتمالاً دیسک محدودیت شما نیست، زیرا اکثر بارهای کاری VPSهای کوچک ابتدا با کمبود RAM یا پهنای باند مواجه میشوند.
در همان روز اول، در حالی که مشغول ده دقیقه اول روی یک VPS جدید هستید، اندازهگیری را انجام دهید و خروجی را در یک فایل نگه دارید. داشتن یک baseline روشی است که بعداً ثابت کنید میزبان کند شده است، نه کد شما. ارائهدهندگانی را ترجیح دهید که کلاس ذخیرهسازی و هرگونه محدودیت IOPS را بهصورت کتبی اعلام میکنند. اگر در یک طرح ذکر شده NVMe و خواندن با queue depth 1 حدود 4 میلیثانیه طول میکشد، شما در واقع از storage شبکه روی یک میزبان مجهز به NVMe استفاده میکنید. این یک مورد منصفانه برای فروش است، اما چیزی متفاوت برای خرید.
FAQ
آیا NVMe همیشه سریعتر از SATA SSD روی یک VPS است؟
خیر. در عمق صف 1، عملکرد هر دو نزدیک به هم است؛ تقریباً 80 تا 150 میکروثانیه برای خواندن 4k، و یک برنامه تکرشتهای تفاوتی بین آنها حس نمیکند. NVMe زمانی پیش میافتد که درخواستهای زیادی در جریان باشند، زیرا AHCI تنها یک صف با عمق 32 دستور ارائه میدهد، در حالی که NVMe هزاران صف عمیقتر دارد. در یک میزبان اشتراکی، بار کاری سایر مهمانان بیش از نوع رسانه بر تأخیر (latency) شما تأثیر میگذارد؛ بنابراین بهجای تکیه بر نام طرح، حجم کاری خود را با fio اندازهگیری کنید.
چگونه بررسی کنم که VPS من واقعاً از NVMe استفاده میکند؟
شما نمیتوانید این موضوع را مستقیماً بررسی کنید، زیرا virtio دستگاه فیزیکی را مخفی میکند. دستور lsblk خروجی vda را بدون رشته مدل نشان میدهد، nvme list چیزی برنمیگرداند و /sys/block/vda/queue/rotational فقط آنچه را که هایپروایزر اعلام میکند گزارش میدهد. بهجای آن، رفتار را اندازهگیری کنید. خواندن تصادفی 4k با عمق صف 1 زیر حدود 0.3 میلیثانیه به معنای استفاده از حافظه فلش محلی است. چندین میلیثانیه تأخیر نشاندهنده وجود یک پرش شبکه در مسیر است. خواندنهای ترتیبی که در نزدیکی 550 MB/s متوقف میشوند، نشاندهنده لینک SATA هستند.
آیا NVMe باعث سریعتر بارگذاری شدن وبسایت من میشود؟
معمولاً خیر. پس از اولین درخواست، لینوکس فایلها را از page cache در RAM سرو میکند، بنابراین دیسک بیکار میماند. سرعت صفحه در یک VPS کوچک معمولاً محدود به زمان CPU برنامه و پهنای باند است. اگر سایت در هر درخواست عملیات نوشتن انجام دهد، دیسک به مسیر بحرانی بازمیگردد؛ برای مثال، یک سبد خرید مبتنی بر دیتابیس که مرتباً commit میکند، زیرا هر commit منتظر تکمیل عملیات flush میماند.
نتیجه خوب برای fio روی یک VPS چیست؟
تا ژوئیه 2026، یک VPS کوچک روی حافظه فلش محلی معمولاً دهها هزار IOPS خواندن تصادفی 4k در عمق صف 32 با تأخیر زیر 0.3 میلیثانیه در عمق صف 1 ارائه میدهد. فضای ذخیرهسازی بلوکی شبکه معمولاً چند هزار IOPS با تأخیر چند میلیثانیه ارائه میدهد. تست را سه بار در ساعات مختلف اجرا کنید. تفاوت زیاد بین نتایج، اطلاعات بیشتری نسبت به میانگین به شما میدهد، زیرا نشان میدهد سایر مهمانان روی میزبان تا چه حد بر شما تأثیر میگذارند.
آیا باید دیتابیس خود را روی فضای ذخیرهسازی بلوکی شبکه قرار دهم؟
میتوانید این کار را انجام دهید و بسیاری از سرویسهای مدیریتشده نیز همین کار را میکنند، اما مسیر commit هزینه آن را میپردازد. هر عملیات flush از شبکه عبور میکند، بنابراین یک اتصال واحد، تراکنشهای کوچک کمتری را در ثانیه نسبت به حافظه فلش محلی commit میکند. در عوض، پایداری (durability) دادهها را در صورت خرابی میزبان به دست میآورید. اگر فضای ذخیرهسازی شبکه را برای یک دیتابیس با نوشتن سنگین انتخاب میکنید، کارها را در تراکنشهای بزرگتر دستهبندی کنید تا تعداد کمتری flush، ردیفهای بیشتری را منتقل کنند.