تسريع النظام الفرعي لقرص Qemu KVM على Linux



أحيانًا أقوم بمهام مختلفة لإعداد الخوادم. منذ فترة ، اقترب مني صاحب شركة استضافة صغيرة بمشكلة مثيرة للاهتمام. يرغب في تشغيل أجهزة Windows الافتراضية تحت KVM على خوادمه ، حيث تم تثبيت Ubuntu 18.04 بالفعل.

ومع ذلك ، أظهر اختباره أن نظام قرص KVM متخلف بشكل جيد عن المؤشرات التي لديه تحت Hyper-V. أراد إطلاق qemu على خوادم Ubuntu الخاصة به لتجنب شراء تراخيص خادم Windows باهظة الثمن (لم يعمل الإصدار المجاني من Microsoft Hyper-V Server بسبب قيوده).

0. التصرف


للاختبار ، استخدمنا Samsung 970 Pro 1TB SSD. قام العميل بفحص نتائج العمل في CrystalDiskMark ، لذلك في المقالة جميع الرسوم البيانية منه.

نظام التشغيل Windows 10 LTSC
وحدة المعالجة المركزية Hyper-V 2

وحدة المعالجة المركزية KVM 2
كانت الخطوة الأولى تحسين أداء الإدخال / الإخراج العشوائي. يعد هذا النوع من التحميل نموذجيًا للأجهزة الافتراضية ، خاصةً تلك التي تستخدم قواعد بيانات متنوعة.

لا يزال Ubuntu (16.04 LTS و 18.04) يستخدم qemu الإصدار 2.11. لذلك ، لا يتم النظر في بعض أحدث كعك qemu في هذه المقالة.

قررنا أننا بحاجة إلى تجنب ربط الحديد بجهاز افتراضي ، لأن هذا يعقد إمكانية نقل الأجهزة الافتراضية ، لذلك اعتبرت خيارات رمي ​​الأقراص / الأقراص / الأقسام المادية في الأجهزة الافتراضية غير مرغوب فيها.

حول حجم ملف الاختبار لـ CrystalDiskMark
, 100 4. , : , .

, , Windows . 100 4 , 40 .

, , 100-1. 4.

1. نستخدم وحدات تخزين LVM ، وليس ملفات لتخزين أقراص الجهاز الظاهري.


المنطق هو هذا. يتم تخزين الملف مع القرص الظاهري في نظام ملفات Linux ، ويقع NTFS داخل الملف نفسه. يستهلك كل نظام ملفات الموارد أثناء عمليات القرص. لذلك ، كلما كان عمق الدمية أصغر ، كان الإدخال / الإخراج أسرع.

إذا تحدثنا عن ملفات qcow2 ، فإن اسمها يعني "Qemu Copy-On-Write" ، وفي الواقع ، لديهم جدول ترجمة خاص بهم في الداخل مسؤول عن أي الكتل مشغولة ، وأيها غير مشغول وأين يوجد.

تستهلك طبقة LVM موارد معالج أقل بكثير من نظام الملفات. أحد أسباب ذلك هو أن الكتل فيه أكبر بكثير من كتلة نظام الملفات النموذجية (4KB). كلما كبرت الكتلة (المدى) على جهاز LVM المادي ، كلما كان IO أسرع وأقل تجزئة.

ولكن حتى بالنسبة لـ SSD العشوائي I / O أبطأ بكثير من المسلسل. لذلك ، عند إنشاء مجموعة التخزين ، سنحدد مدى كبير جدًا: 256 ميجابايت.

يجب متابعة القراءة مسبقًا على وحدة التخزين المنطقية ، لأنها تنفق IO بدون فوز ، نظرًا لأنه لا يوجد أحد يقوم الآن بإلغاء تجزئة الأقراص في Windows على SSDs.

LVM مناسب تمامًا لاستضافة الأجهزة الافتراضية. يمكن تخزين أحجام LVM بسهولة بين الأقراص المادية ؛ وهناك لقطات وتغيير الحجم عبر الإنترنت. علاوة على ذلك ، يمكن لـ Virt-manager (libvirt) إنشاء وحدات تخزين منطقية من خارج الصندوق لأقراص الجهاز الظاهري من مجموعة Volume.

تبدو القدرة على إنشاء مجلدات رفيعة جذابة أيضًا ، ولكن نظرًا لأن الحجم الرقيق هو طبقة إضافية من التجريد ، فمن الواضح أنه سيؤدي إلى تدهور أداء IO. بالإضافة إلى ذلك ، لا يمتلك libvirt طريقة أنيقة لإنشاء الأقراص تلقائيًا للأجهزة الافتراضية في مجموعة رقيقة.

#    SSD    (volume group)
pvcreate /dev/nvme1n1p1

#    win    (extent) 256.
vgcreate -s 256M win_pool /dev/nvme1n1p1

#    vm1.    C
lvcreate -n vm1 -L 100G win_pool

#      (read ahead)
lvchange -r none /dev/win_pool/vm1

1.1. صوت رفيع كقرص و / أو إعدادات حجم منطقية للقطات


إذا كنت ترغب في استخدام تجمع رقيق يمكنك من خلاله إنشاء مجلدات رقيقة ، فمن المنطقي تعيين حجم القطعة إلى 4 ميجابايت ، وهو أكبر بكثير من الحجم الافتراضي البالغ 64 كيلوبايت.
مما يستتبع عمل أسرع لهذه الطبقة من التجريد.

تعمل آلية اللقطة في LVM تقريبًا على نفس التعليمات البرمجية للأحجام الرقيقة ، لذا ستكون الإعدادات نفسها لزيادة سرعة اللقطة.

lvcreate -c 4m -L 300G -T -Zn win_pool/thin

-Znيعطل الخيار الكتابة فوق القطعة بالأصفار عند التظليل ، مما يزيد من سرعة العمل.

إعدادات lvm.conf أو ملف مشابه (مثل lvmlocal.conf):

thin_pool_chunk_size = 4096
thin_pool_zero = n

يمكنك تحديد الحجم الأمثل للقطعة من خلال إكمال الاختبار بالأمر التالي ، واختيار القيمة --blocksize:

fio --name=randwrite --filename=/dev/nvme0n1p9 --size=10G --ioengine=libaio --iodepth=1 --buffered=0 --direct=1 --rw=randwrite --blocksize=4m

يمكنك عرض الحجم الحالي للمقطع باستخدام الأمر:

lvs -ao name,chunksize

2. زيادة عدد المعالجات المنطقية المخصصة لكل آلة افتراضية KVM يحسن أداء القرص


10 وحدة معالجة مركزية8 وحدة المعالجة المركزية4 وحدة المعالجة المركزية

من الواضح أنه لا يكاد أي شخص سيخصص 10 معالجات للجهاز الافتراضي ، ولكن كان من المثير للاهتمام النظر إلى الحالة القصوى.

يعتمد بالفعل على عدد المعالجات المجانية. في رأيي ، من غير المناسب تخصيص أكثر من 4. مع عدد الخيوط يساوي 8 ، حصلنا على أقصى أداء عشوائي للقراءة والكتابة. هذه هي خصوصية CrystalDiskMark 6.0.2 ، حيث يقوم الاختبار الثاني بإجراء 8 خيوط.

يمكننا من خلاله استنتاج أنه من الجيد أن يكون لديك معالج منطقي واحد لكل مهمة تستخدم IO بنشاط.

3. نستخدم صفحات ضخمة من ذاكرة الوصول العشوائي (hugepages) لتجنب تدهور الأداء بسبب تجزئة ذاكرة الوصول العشوائي


يمكن أن تكون هذه الحزمة مفيدة عندما نحتاج إلى معلومات مختلفة حول hugepages أثناء التشغيل.

apt install hugepages

تحرير /etc/default/grub:

GRUB_CMDLINE_LINUX="default_hugepagesz=1GB hugepagesz=1G hugepages=64"

في هذه الحالة ، تم تخصيص 64 جيجا بايت من الذاكرة لجميع الأجهزة الافتراضية كصفحات هوج. في حالتك قد يكون هناك أقل / أكثر.

نطبق هذه الإعدادات على GRUB بحيث تصبح نشطة في المرة التالية التي يتم فيها تشغيل النظام:

grub-mkconfig -o /boot/grub/grub.cfg

تحرير تكوين الجهاز الظاهري:

virsh edit vm_name

أضف:

<memoryBacking>
  <hugepages/>
</memoryBacking>

4. إضافة دفق مخصص لكل جهاز افتراضي لخدمة IO


تحتاج إلى إضافة ما تم تمييزه بالخط العريض. نستخدم virsh، كما في الفقرة السابقة.

<iothreads>1</iothreads>

<disk type='block' device='disk'>
<driver name='qemu' type='raw' cache='none' io='threads' iothread='1'/>
<source dev='/dev/win/terminal'/>
<target dev='vda' bus='virtio'/>
<boot order='2'/>
<address type='pci' domain='0x0000' bus='0x04' slot='0x00' function='0x0'/>
</disk>


4.1. writeback


لتسريع الكتابة غير المقصودة على القرص ، ولكن مع زيادة خطر فقدان البيانات ، يمكنك استخدام cache=writebackالفقرة السابقة. يمكن استخدامه فقط إذا كانت هناك ثقة كبيرة في جودة الطاقة والنسخ الاحتياطي وفي وجود النسخ الاحتياطية.

5. إعدادات النظام الفرعي للقرص في Virt Manager


ناقل القرص:
تنسيق التخزين VirtIO :
وضع ذاكرة التخزين المؤقت الأولية :
وضع إعادة الإدخال / الإخراج: مؤشرات الترابط

5.1. تكوين النظام الفرعي للقرص من خلال ملف التكوين


يدعم Qemu 2.11 (الذي يستخدمه Ubuntu حاليًا) نوعين من الأجهزة الافتراضية للقرص: Virtio-blk و Virtio-scsi. عند تحديده في Virt Manager Disk bus: VirtIO، هذا يعني استخدام الجهاز Virtio-blk.

في جميع الحالات ، فإن Virtio-blk أفضل في السرعة ، على الرغم من حقيقة أنه في إصدار qemu الذي تم اختباره ، لا يزال لا يدعم TRIM ، على عكس Virtio-scsi (وهو يدعمه بالفعل منذ الإصدار 5.x ).

من وجهة نظر سرعة IO للقرص ، يكون Virtio-scsi منطقيًا فقط في الحالات الغريبة ، على سبيل المثال ، عندما تحتاج إلى توصيل مئات الأقراص بجهاز افتراضي.

6. أثناء تثبيت Windows ، قم بتثبيت برنامج تشغيل VirtIO


وإلا ، فلن يكون القرص متاحًا لنظام التشغيل. للقيام بذلك ، استخدم صورة برنامج التشغيل ، التي نقوم بتوصيلها مسبقًا بالجهاز الظاهري.

7. النتائج بعد تطبيق جميع التعديلات


في الواقع ، لم يتم استخدام القرص 4.1 ، لأنني لم أكن متأكدًا من موثوقية مصدر الطاقة من العميل.

وحدة المعالجة المركزية Hyper-V 2

وحدة المعالجة المركزية KVM 2

وحدة المعالجة المركزية KVM 4

عليك أن تفهم أن هذه النتائج لها اصطلاح معين ، لأنه في كل مرة تبدأ فيها CrystalDiskMark ، تكون القيم مختلفة قليلاً.

KVM من خارج مربع
2 وحدة المعالجة المركزية
KVM بعد القرص
2 وحدة المعالجة المركزية

نرى أنه كان من الممكن تسريع عمل النظام الفرعي للقرص بشكل كبير في qemu (kvm) بنفس عدد النوى. تم تسريع الكتابة بمتوسط ​​58٪ ، والقراءة بنسبة 25٪.

عناصر النجاح الرئيسية : استخدام مجلدات LVM بدلاً من ملفات qcow2 ، وإدخال / إخراج منفصل ، و hugepages.

توجيه الأخطاء الملحوظة إلى PM. أقوم بزيادة الكارما لذلك.

PS vhost-user-blk و vhost-user-nvme


خلال التجارب ، تم أيضًا تجميع Qemu 2.12 و الإصدار 3. تم اختبار الخيار vhost-user-blk للقرص.

في النهاية ، كان الأمر أسوأ من العمل المبتكر.


وحدة المعالجة المركزية vhost-user-blk 4

وحدة المعالجة المركزية Virtio-blk 4

لاستخدام vhost-user-nvme ، كان من الضروري تصحيح qemu ، وقد أدى هذا الخيار إلى تعقيد التحديث التلقائي للخوادم قيد الإنتاج ، لذلك لم يتم اختباره.

PPS SPDK


صممت Intel هذا الإطار لتحقيق مؤشرات أداء متميزة لأنظمة الأقراص في الأجهزة الافتراضية التي يجب تشغيلها على معالجاتها.

لجعل spdk يعمل بشكل جيد ، يذهبون إلى الكثير من الحيل - يخصصون نواة منفصلة لها ، ويضعون spdk ونواة الآلة الافتراضية في مقبس واحد. قم بتحميل الجهاز الظاهري في جزء متجاور من الذاكرة. إذا قمت بتطبيق مثل هذه الإجراءات على الأمر العادي ، فستعمل أيضًا بشكل أسرع.

SPDK قادر على العمل في 3 أوضاع: vhost-user-scsi و vhost-user-blk و vhost-user-nvme. الوضع الثاني متاح فقط في qemu من 2.12 ، وهو غير متوفر حتى الآن في ubuntu. يكون وضع vhost-user-nvme عمومًا تجريبيًا كبيرًا - تحتاج إلى تصحيح qemu لذلك. حاليا ، يعمل مضاهاة scsi فقط وهو بطيء.

هناك قيود أكثر خطورة لوضع vhost-user-scsi - لا يمكن تشغيل spdk.
تأكد من أن bootindex = 2 خيار Qemu مُعطى لجهاز vhost-user-scsi-pci.
يتم تعيين السجلات عندما يستخدمون برنامج التشغيل الخاص بهم لمشاركة أقراص SSD على أجهزة متعددة وإعادة توجيهها على أنها vhost-user-nvme. نهج ثقب الحديد لم يناسبنا.

كان الانطباع أنه من الطبيعي استخدام SPDK فقط مع تنفيذها للأقراص المنطقية (التي تختلف تمامًا عن lvm القياسي). هذه دراجة ذاتية الصنع مع صورها واستنساخها. الفرق كلها مختلفة عن LVM.

الصعوبة في تكوين SPDK ، ودعم وإمكانية نقل الأجهزة الظاهرية ، بالإضافة إلى الارتباط بمعالجات Intel ، تحولت عن استخدامها.

شكر وتقدير


شكرا للصورة TripletConcept . من الأفضل مشاهدته بالحجم الكامل في نافذة منفصلة.

للحصول على إذن لمشاركة مواد العمل -st_neon




يمكنك طلب جهاز افتراضي مع SSD من RUVDS للقسيمة أدناه. توجيه الأخطاء الملحوظة إلى PM. أقوم بزيادة الكارما لذلك.




All Articles