Иногда я берусь за различные задачи по настройке серверов. Некоторое время назад ко мне обратился владелец небольшой хостинговой компании, с интересной проблемой. Он хотел бы на своих серверах, где уже стоял Ubuntu 18.04, запускать виртуальные машины с Windows под KVM.
Однако проведённое им тестирование показало, что дисковая система KVM прилично отставала от показателей, которые у него были под Hyper-V. Он хотел раскочегарить qemu на своих Ubuntu серверах, чтобы избежать закупок дорогих серверных лицензий Windows (бесплатная версия Microsoft Hyper-V Server не устраивала из-за своих ограничений).
0. Диспозиция
Для тестирования использовался SSD Samsung 970 Pro 1TB. Заказчик проверял результаты работы в CrystalDiskMark, поэтому далее в статье все графики из него.
Windows 10 LTSC | Hyper-V 2 CPU |
KVM 2 CPU |
---|---|---|
В Ubuntu (16.04 LTS и 18.04) до сих пор используется qemu версии 2.11. Поэтому некоторые плюшки самых последних qemu в этой статье не рассмотрены.
Мы решили что нам нужно избежать привязывания железа к виртуальной машине, так как это осложняет переносимость виртуальных машин, поэтому варианты с прокидыванием SSD/физических дисков/разделов в виртуалки были признанны нежелательными.
Однако, так как каждый раз виртуальная машина запускалась заново, кеш Windows сбрасывался и не оказывал влияние на результаты. Результаты для области 100МБ и 4ГБ отличались в пределах погрешности, но время было в 40 раз больше.
Тестирований за время настройки было проведено огромное количество, чтобы задача не затянулась на месяцы, основная часть испытаний была проведена с областями размером 100МБ-1ГБ. И только решающие испытания были проведены с областями 4ГБ.
1. Используем LVM-тома, а не файлы для хранения дисков виртуальных машин.
Логика такая. Файл с виртуальным диском хранится в файловой системе Linux, внутри самого файла находится NTFS. Каждая файловая система потребляет ресурсы при дисковых операциях. Поэтому чем меньше глубина матрёшки, тем быстрее ввод/вывод.
Если же говорить о файлах qcow2, то их название расшифровывается как «Qemu Copy-On-Write» и, фактически, внутри них есть своя таблица трансляции, которая отвечает за то какие блоки заняты, какие нет и где что находится.
Слой LVM потребляет значительно меньше процессорных ресурсов, чем файловая система. Одна из причин этого то, что блоки в нём значительно больше, чем типичный блок файловой системы (4КБ). Чем больше блок (extent) на физическом устройстве LVM, тем более быстро происходит IO и тем меньше фрагментация.
А ведь даже для SSD случайный ввод/вывод значительно медленнее, чем последовательный. Поэтому при создании Volume Group мы укажем очень большую величину extent: 256MB.
Read ahead на логическом томе стоит отключить, так как он расходует IO без выигрыша, так как теперь никто не занимается дефрагментацией дисков в Windows на SSD.
LVM довольно удобно использовать для хостинга виртуальных машин. LVM-тома легко переносимы между физическими дисками, есть снимки (snapshot), изменение размера в режиме онлайн. Тем более, что virt-manager (libvirt) умеет из коробки создавать логические тома под диски виртуальных машин из Volume group (группы томов).
Привлекательной выглядит также возможность создать thin volumes («тонкие» тома), но если учесть, что тонкий том — это дополнительный слой абстракции, то, очевидно, что он будет ухудшать производительность 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. Thin volume как диск и/или настройки логических томов для снимков
Если вы хотите использовать thin pool, в котором будете создавать тонкие тома, то имеет смысл установить размер чанка у пула в 4МБ, что значительно больше размера по-умолчанию в 64КБ.
Что повлечёт более быструю работу этого слоя абстракции.
Механизм снимков в LVM работает практически на том же самом коде, что и тонкие тома, поэтому для увеличения скорости снимков (snapshot) настройки будут теми же самыми.
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 CPU | 8 CPU | 4 CPU |
---|---|---|
Понятно, что вряд ли кто будет выделять на виртуалку 10 процессоров, но было интересно посмотреть на крайний случай.
Тут уже зависит от числа свободных процессоров. На мой взгляд больше 4-х выделять нецелесообразно. При числе потоков равному 8 мы получили максимальную производительность случайного чтения и записи. Это специфика CrystalDiskMark 6.0.2, в котором второй тест проводит 8-ю потоками.
Из чего можно сделать вывод, что хорошо иметь по одному логическому процессору на каждую задачу, активно использующую IO.
3. Используем огромные страницы оперативной памяти (hugepages), чтобы избежать снижения производительности из-за фрагментации RAM
Этот пакет может пригодиться, когда нам понадобится различная информация о hugepages в процессе эксплуатации.
apt install hugepages
Правим
/etc/default/grub
:GRUB_CMDLINE_LINUX="default_hugepagesz=1GB hugepagesz=1G hugepages=64"
В данном случае было выделено 64ГБ памяти для всех виртуальных машин в виде hugepages. В вашем случае может быть меньше/больше.
Применяем эти настройки для 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
Disk bus: VirtIO
Storage format: raw
Cache mode: writeback
IO mode: threads
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 CPU |
KVM 2 CPU |
KVM 4 CPU |
---|---|---|
Нужно понимать, что эти результаты грешат некой условностью, так как при каждом запуске CrystalDiskMark значения немного отличаются.
KVM из коробки 2 CPU |
KVM после твиков 2 CPU |
---|---|
Мы видим, что удалось существенно ускорить работу дисковой подсистемы в qemu (kvm) при одном и том же числе ядер. Запись была ускорена в среднем на 58%, а чтение на 25%.
Основные элементы успеха: использование LVM-томов вместо файлов qcow2, отдельный поток ввода/вывода и hugepages.
Замеченные ошибки направляйте в личку. Повышаю за это карму.
P.S. vhost-user-blk и vhost-user-nvme
В ходе экспериментов были также и скомпилированы Qemu 2.12 и 3-й версии. Тестировалась опция vhost-user-blk для диска.
В итоге она работала хуже, чем virtio-blk.
vhost-user-blk 4 CPU |
virtio-blk 4 CPU |
---|---|
Для использования vhost-user-nvme нужно было патчить qemu, этот вариант усложнял автоматическое обновление серверов в продакшене, поэтому не был протестирован.
P.P.S. SPDK
Intel разработала этот фреймворк для достижения выдающихся показателей производительности у дисковых систем в виртуальных машинах, которые должны работать на её процессорах.
Чтобы заставить spdk хорошо работать идут на массу ухищрений — выделяют ему отдельные ядра, размещают ядра spdk и виртуальной машины в одном сокете. Загружают виртуальную машину в непрерывный кусок памяти. Если такие меры применять к обычному virtio-blk, то он тоже будет быстрее работать.
SPDK способен работать в 3-х режимах: vhost-user-scsi, vhost-user-blk и vhost-user-nvme. Второй режим доступен только в qemu от 2.12, который ещё не доступен в ubuntu. Режим vhost-user-nvme вообще мегаэкспериментальный — для него нужно патчить qemu. На текущий момент работает только эмуляция scsi и она медленная.
Есть ещё одно серьёзное ограничение для режима vhost-user-scsi — диск spdk не может быть загрузочным.
Make sure bootindex=2 Qemu option is given to vhost-user-scsi-pci device.Рекорды ставятся, когда они с помощью своего драйвера разделяют SSD на несколько устройств и прокидывают их как vhost-user-nvme. Подход с прокидыванием железа нам не подходил.
Сложилось впечатление, что нормально использовать SPDK можно только с их реализацией логических дисков (которая совершенно отличается от стандартных lvm). Это такой самопальный велосипед со своими снимками и клонированием. Команды все отличаются от LVM.
Сложность в настройке SPDK, поддержке и переносимости виртуальных машин, а также привязанность к процессорам Intel отвернула от его использования.
Благодарности
За изображение спасибо TripletConcept. Его лучше смотреть в полном размере в отдельном окне.
За разрешение поделиться рабочими материалами — st_neon
Вы можете заказать виртуальную машину с SSD у RUVDS по купону ниже.
Замеченные ошибки направляйте в личку. Повышаю за это карму.
Silnur
Так вроде Microsoft Hyper-V Server бесплатен.
inetstar Автор
Он ставится на голое железо и управляется из консоли, что было неудобно для заказчика. В в составе Windows Server с ролью Hyper-V нужно платить за сам Windows Server.
Silnur
Мне кажется вы путаете Windows Server с ролью Hyper-V и Microsoft Hyper-V Server.
Hardened
"Он хотел бы на своих серверах, где уже стоял Ubuntu 18.04, запускать виртуальные машины с Windows под KVM."
"Он хотел раскочегарить qemu на своих Ubuntu серверах, чтобы избежать закупок дорогих серверных лицензий Windows Server"
Я вас поздравляю — нарушает правила лицензирования Microsoft. Чтобы иметь право использовать Windows Server в гостевой системе должен быть корректно отлицензирован хост. И не важно, какой гипервизор используется…
edo1h
… и сколько ядер доступно виртуалке — лицензировать надо все физические.
inetstar Автор
А меня за что? Я только настраивал сервер.
Кстати, в гостевых системах использовалась Windows 10 Pro, а не Server.
NoOne
Для клиентский Windows в среде виртуализации требуется Software Assurance или отдельные лицензии VDA
Hardened
Все сложнее. Multitenant Hosting десктопной Windows требует отдельной авторизации от Microsoft. В России я только РТК знаю с такой
navion
Это разве не про сдачу в аренду? А то получается, что VDI у всех развёрнут незаконно.
Hardened
Multitenant Hosting Rights for Windows 10
Customers who buy Windows Per User licenses through Microsoft Volume Licensing will need to engage with an Authorized QMTH Partner to make use of their multitenant hosting rights for Windows 10 to host their Windows virtual machines on third-party multitenant hardware.
In addition, a customer who buys qualifying Windows 10 subscriptions with virtualization use rights via Microsoft Cloud Agreement subscription will need to engage with an Authorized QMTH Partner to make use of their multitenant hosting rights for Windows 10.
Customers do not need to engage an Authorized QMTH Partner for the following scenarios for qualifying Windows 10 products:
• Microsoft Azure environment
• Customers with on-premise dedicated use rights
www.microsoft.com/en-us/CloudandHosting/licensing_sca.aspx
Hardened
Это если компания на собственной инфраструктуре делает виртуализацию рабочих столов. С переносом к хостерам все несколько сложнее.
P6i
Товарищу майору будите рассказывать, что вы, только, настраивали сервер
Loggus66
Хост лицензирован корректно, согласно условиям GNU GPL, не так ли?
Hardened
Гостевой Windows Server лицензируется по физическому хосту. Если на хост не назначены лицензии Microsoft в необходимом количестве, то гость Windows Server вы не имеете права использовать.