Qemu тормозит в windows

Обновлено: 06.07.2024

В следствии обновления и перехода на CentOS на новую версию 7, мы на dedicated серверах часто начали сталкиваться с тормозами сервера на CentOS, при том что мощный конфиг, но все равно I/O 99% и ничего не сделаешь с этим. Пробовали менять и режимы работы PHP, ничего не давало результата, на сервере на котором должно работать 150 сайтов легко, с трудом работает 20.

Перепробовали все, в поисках проблемы, и обнаружили довольно интересный факт, который внесли разработчики CentOS в новой 7 версии. Оказывается, они решили по-умолчанию ставить процессор в энергосберегающий режим. проверить так ли это, можно довольно просто, достаточно авторизоваться по SSH на своем сервере и выполнить команду:

cat / sys / devices / system / cpu / cpu * / cpufreq / scaling_governor

Если Вы видите вот такой вот ответ:

cat / sys / devices / system / cpu / cpu * / cpufreq / scaling_governor

powersave
powersave
powersave
powersave

Есть следующие режимы работы процессора:

  • powersave — энергосберегающий (наша проблема, тормозит все и ужасно)
  • ondemand — меняет частоту по требованию (но почему во время резких скачков нагрузки забывает это делать)
  • performance — максимальная частота всегда

Узнать частоту ядер процессора:

Можно поменять режим работы командой:

Есть и другие, но они значительно замедляют работу Вашего сервера. Что бы решить эту проблему раз и навсегда и наслаждаться быстрой работой сервера, достаточно выполнить следующую команду:

И процессор начнет работать на максимальной частоте, Вы сразу же увидите падение нагрузки на 20-40%.

Если у Вас возникли сложности, Вы всегда можете обратится к нам, за помощью.

На Debian/Ubuntu системах нужно установить:

VIRTUALIZATION TUNING AND OPTIMIZATION GUIDE

Performance Tuning in centos7

BIOS setting
Enable X2APIC

Bonding Mode: IEEE 802.3ad Dynamic link aggregation
Transmit Hash Policy: layer2 (0)
MII Status: up
MII Polling Interval (ms): 100
Up Delay (ms): 0
Down Delay (ms): 0

802.3ad info
LACP rate: slow
Min links: 0
Aggregator selection policy (ad_select): stable
System priority: 65535
System MAC address: 7c:fe:90:de:08:38
Active Aggregator Info:
Aggregator ID: 1
Number of ports: 2
Actor Key: 1
Partner Key: 449
Partner Mac Address: 38:bc:01:79:33:51

Slave Interface: enp131s0f0
MII Status: up
Speed: 25000 Mbps
Duplex: full
Link Failure Count: 0
Permanent HW addr: 7c:fe:90:de:08:38
Slave queue ID: 0
Aggregator ID: 1
Actor Churn State: none
Partner Churn State: none
Actor Churned Count: 0
Partner Churned Count: 0
details actor lacp pdu:
system priority: 65535
system mac address: 7c:fe:90:de:08:38
port key: 1
port priority: 255
port number: 1
port state: 61
details partner lacp pdu:
system priority: 32768
system mac address: 38:bc:01:79:33:51
oper key: 449
port priority: 32768
port number: 1
port state: 61

Slave Interface: enp131s0f1
MII Status: up
Speed: 25000 Mbps
Duplex: full
Link Failure Count: 0
Permanent HW addr: 7c:fe:90:de:08:39
Slave queue ID: 0
Aggregator ID: 1
Actor Churn State: none
Partner Churn State: none
Actor Churned Count: 0
Partner Churned Count: 0
details actor lacp pdu:
system priority: 65535
system mac address: 7c:fe:90:de:08:38
port key: 1
port priority: 255
port number: 2
port state: 61
details partner lacp pdu:
system priority: 32768
system mac address: 38:bc:01:79:33:51
oper key: 449
port priority: 32768
port number: 97
port state: 61
Get CPU and PCIE adapter topology
Pin different cpu cores to different adapter
Disable irqbalance

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
Enable HT
0,1,10,11,2,24,25,26,27,28,29,3,30,31,32,33,34,35,4,5,6,7,8,9,
12,13,14,15,16,17,18,19,20,21,22,23,36,37,38,39,40,41,42,43,44,45,46,47,
cpu numa node number is: 2
cpu-hex cpu-hex numa_node
200 200000000 0
40 40000000 0
8 8000000 0
1 1000000 0
10 10000000 0
2 2000000 0
20 20000000 0
80 80000000 0
400 400000000 0
100 100000000 0
4 4000000 0
800 800000000 0
400000 400000000000 1
8000 8000000000 1
800000 800000000000 1
20000 20000000000 1
40000 40000000000 1
1000 1000000000 1
100000 100000000000 1
80000 80000000000 1
10000 10000000000 1
2000 2000000000 1
200000 200000000000 1
4000 4000000000 1
Numa node0
1
2
3
02:00.0 Non-Volatile memory controller: Intel Corporation Device 0a53 (rev 02)
03:00.0 Non-Volatile memory controller: Intel Corporation Device 0a53 (rev 02)
04:00.0 Serial Attached SCSI controller: LSI Logic / Symbios Logic SAS3008 PCI-Express Fusion-MPT SAS-3
Numa node1
Next time , I will change etheret adapter to numa 0

One thought on “ Низкая производительность виртуальных серверов QEMU-KVM, высокий I/O Wait 99% на CentOS 7 ”

tuned-adm active
tuned-adm profile throughput-performance

Тесты производительности 1С от инфостарта подняли результаты в 2 раза после этого тюнинга на CentOS 7.7.
Так что не только для виртуалок актуально, PostgreSQL + Сервер 1С Предприятие тестировалось на физической машине.

Добавить комментарий Отменить ответ

Этот сайт использует Akismet для борьбы со спамом. Узнайте, как обрабатываются ваши данные комментариев.

Примечание: Данная статья демонстрирует вариант оптимизации, который заметно увеличивает производительность в конкретном случае. Представленные результаты тестирования не претендуют на точность, их основная цель продемонстрировать наличие эффекта от применения описываемых оптимизаций.

Содержание.

Вступление.

Windows 10 чрезвычайно тяжёлая ОС с множеством активных служб, вызывающих пилообразную нагрузку и огромное количество прерываний, поэтому без оптимизации работы виртуальной машины не обойтись.

Программы для тестирования.

Данный нехитрый набор достаточен для оценки производительности гостевой ОС Windows.

    — предназначена для измерения задержек прерываний. Чем выше задержки, тем сильнее проявляются «заикания», включая потрескивание звука. — тестирование производительности процессора. — тестирование 3D производительности. — тестирование 3D производительности.

Пример результатов тестирования без оптимизации.

Cinebench.


После оптимизации результат улучшится на

Unigine Superposition.


После оптимизации результат улучшится на

Unigine Valley.


После оптимизации результат улучшится на

Переключение процессора в режим производительности.

Зашкаливающие задержки прерываний выглядят подобным образом:


По моим наблюдениям, именно энергоэффективный режим работы процессора является ключевым источником проблем с производительностью и отзывчивостью виртуальной машины.

Настройка режима производительности процессора.

Потребуется переключить режим управления частотой процессора на performance. Тем самым хост будет предоставлять максимум производительности для виртуальной машины.

Вывести доступные режимы:

В выводе будет подобное:

Проверить режим работы процессора:

Скорее всего, в выводе будет ondemand — сбалансированный режим. Его необходимо переключить на режим performance.

Переключение можно осуществить следующей командой:

Вот и всё. С performance в гостевой ОС не будет заиканий и треска при проигрывании звука.


Важный нюанс для Ubuntu.

На момент 2021 года в Ubuntu и её деривативах всё ещё присутствует демон ondemand, который не следует путать с режимом управления частотой процессора. В стародавние времена он служил для динамичного управления энергосбережением, а ныне в нём нет надобности. Если этот демон включён, то после перезагрузки хоста вновь будет включен режим ondemand, а не ранее включенный performance.

Стоит проверить активен ли демон ondemand:

Если выключен, то вывод будет таким:

Если включен, то потребуется отключить следующим образом:

После этого режим performance не будет переключаться на ondemand после перезагрузки.

Предварительный результат улучшения производительности.

Только за счёт переключения режима управления частотой процессора удалось получить более 15% к производительности ядер для виртуальной машины:


Для 3D графики результат скромнее, но эффект хорошо заметен.

Было: 8695 очков. Стало: 8776.


Было: 3457. Стало: 3790.


Пример настроенной конфигурации.

Отключение memballoon.

По конфигурации начнём с конца и по совместительству самого простого.

Memballoon — специальный драйвер, который обеспечивает подкачку памяти для гостевой ОС, если исчерпывается выделенная память.

Для поддержки memballoon в Win10 нужен специальный драйвер, который лишний раз укажет на факт виртуализации, который так старательно маскировали в предыдущей статье. Ко всему прочему драйвер ранее вызывал проблемы при совместном использовании с vfio, служащего для проброса видеокарты. Поэтому оптимальнее выключить.

Отключение осуществляется через редактирования конфигурации виртуальной машины. Конфигурация membaloon находится в блоке devices:


По умолчанию блок с memballoon выглядит подобным образом:

Блок с выключенным memballoon выглядит так:


На этом по memballoon всё.

Настройка дисковых устройств.

Конфигурация дисковых устройств находится в блоке devices.

Пример настроенной конфигурации:


Разбор первой строки:

Разбор второй строки:

Разбор третьей строки:

Разбор четвёртой строки:

В пятой строке оптимальны значения по умолчанию.

Настройка SPICE.

В предыдущей статье для управления виртуальной машиной был выбран протокол SPICE. В данном случае виртуальная машина запускается на локальном компьютере, а по умолчанию конфигурация SPICE больше рассчитана для удалённого доступа. Поэтому следует настроить для локального применения.

По умолчанию конфигурация выглядит подобным образом:


Отключение прослушки сети и сжатия пакетов заметно снижает уровень задержек. Оптимизированная конфигурация выглядит так:


CPU Pinning — vcpupin.

Это прикрепление (pinning) потоков физического процессора к логическим ядрам виртуальной машины (vcpu). Благодаря прикреплению, обработка процессов виртуальной машины будет иметь несколько более высокий приоритет, что заметно снизит задержки прерываний. По умолчанию нагрузка логических ядер виртуальной машины распределяется между всеми потоками физического процессора. В виду того, что системе необходимо налету балансировать распределение ресурсов процессора между хостом и виртуальной машиной, время задержек прерываний для ряда задач может быть не оптимальным. Если наблюдается недостаточная отзывчивость гостевой ОС и проявляется потрескивание (заикание) звука, то стоит попробовать прикрепить потоки к логическим ядрам виртуальной машины.

Структура потоков процессора.

Перед прикреплением потоков к виртуальной машине необходимо ознакомиться со структурой логических ядер (потоков) физического процессора. У Intel и AMD она различается. В данном примере будет рассмотрен вариант с Intel.

Со структурой можно ознакомиться при выводе возможностей хоста с помощью утилиты virsh:

Будет отображён большой вывод с xml-структурой. В нём показаны возможности хоста в той же компоновке, как в xml-конфигурации виртуальной машины. Пример части вывода для системы с процессором Intel i7 6800K (12 логических ядер):


Информация о структуре потоков находится в блоке <cpus>:


В современных процессорах используется технология гиперпоточности. Её особенностью является то, что одно физическое ядро предстаёт в виде двух логических ядер (потоков), что позволяет распределить вычислительную нагрузку более оптимально.

В данной статье в качестве примера рассматривается Intel i7 6800K с шестью физическими ядрами, что с гиперпоточностью даёт двенадцать логических ядер (потоков). Каждое логическое ядро относится к конкретному физическому ядру. Отсчёт логических ядер начинается от 0.

Из иллюстрации следует, что для шести физических ядер (core_id) используется двенадцать логических ядер (cpu id), тем самым каждому физическому ядру родственны по два потока:

  1. Логическое ядро cpu относится к первому физическому ядру core_id=0, которому принадлежат потоки 0 и 6.
  2. Второе логическое cpu к физическому core_id=1 с потоками 1 и 7.
  3. Третье cpu core_id=2 с потоками 2 и 8.
  4. Четвёртое cpu core_id=3 с потоками 3 и 9.
  5. Пятое cpu core_id=4 с потоками 4 и 10.
  6. Шестое core_id=05 core_id=5 с потоками 5 и 11.
  7. Седьмое логическое ядро cpu снова относится к первому физическому ядру core_id=0 с теми же родственными потоками 0 и 6. Далее аналогично.
  8. Восьмое core_id=7 ко второму core_id=1.
  9. Девятое core_id=8 к третьему core_id=2.
  10. Десятое core_id=9 к четвёртому core_id=3.
  11. Одинадцатое core_id=10 к пятому core_id=4.
  12. Двенадцатое core_id=11 к шестому core_id=5.

Выглядит причудливо, но разобраться можно.

Примечание: Структура потоков у Intel и AMD отличается. У AMD они идут один за другим. Пример: первое физическое ядро — потоки 0 и 1; второе ядро — 2 и 3 и так далее.

Так же структуру потоков можно вывести следующей командой:

  • Столбец CPU перечислены номера (id) логических ядер. Отсчёт от 0.
  • CORE номера физических ядер, к которым относятся логические ядра. В виду того, что на одно физическое ядро приходится два логических ядра (потока), номер (id) в столбце повторяется.

Субъективно, такой вывод существенно менее очевиден, поэтому рекомендую первый метод.

Прикрепление потоков к виртуальным логическим ядрам виртуальной машины.

Прикреплённые потоки процессора не становятся изолированными для использования хост-системой. По умолчанию для логических ядер виртуальной машины (vcpu) задействованы все потоки хоста.

Для 8 логических ядер виртуальной машины это выглядит так:

Для снижение задержек прерываний рекомендуют оставить в пользу хоста первое физическое ядро с его двумя потоками, так как оно нагружено различными программами, выполняемыми в хост-системе.

Примечание: В старых версиях qemu-kvm для Windows-гостей рекомендовалось обратное — прикреплять потоки от начала. Это было связано с программными недоработками, приводившими к сильному падению производительности виртуальной машины с Windows. Но в поздних версиях qemu-kvm эта проблема устранена.

В данном случае рассмотрен вариант, в котором для хост-системы оставлено четыре потока:

  • Первое физическое ядро: 0 и 6.
  • Второе физическое ядро: 1 и 7.

Да, из-за сокращения числа задействованных потоков производительность будет несколько ниже, но в данном случае целью является снижение задержек прерываний.

Первые четыре потока двух физических ядер можно задействовать для эмулятора qemu (emulatorpin), чтобы его работа не занимала процессорное время ядер, прикреплённых к виртуальной машине. Подробности далее.

Прикрепление осуществляется в блоке cputune. Настроенная конфигурация выглядит так:


В данном примере для виртуальной машины выделено 8 потоков из 12.

Далее по аналогии.

На этом заканчивается самое соновное о прикреплении потоков физического процессора к логическим ядрам виртуальной машины.

Аппендикс об iothread.

В ряде публикаций можно увидеть прикрепление потоков для iothread. Это обработчик ввода-вывода для накопителей. В данном случае используется драйвер SATA, а iothread работает только с драйверами virtio-scsi и virtio-blk, поэтому в нём нет нужды.

Настройка планировщика.

Предпочтительным является режим FIFO (First In-First Out). Сразу стоит оговориться, что для ряда задач это может наоборот ухудшить время задержек прерываний, поэтому следует применять с осторожностью.

Настроенный вариант выглядит так:


Настройка таймеров.

Ознакомительный материал:

По умолчанию блок с таймерами имеет подобный вид:

Настройка.

Вывести доступные для использования системные таймеры:

В выводе будет подобное: tsc hpet acpi_pm

Проверить какой таймер используется хостом:

В выводе будет tsc.

Настроенный вариант имеет следующий вид:

Добавлены следующие строки:

По таймерам почти всё, остаётся ещё один момент.

Настройка hugepages.

Использование больших страниц для задач с интенсивной нагрузкой на оперативную память заметно улучшает производительность. Ключевым нюансом является то, что зарезервированная память будет изъята для использования хост-системой, поэтому крайне важно удостовериться, что оставшейся памяти достаточно для работоспособности.

Перед началом настройки стоит убедиться, что выделение больших страниц включено на уровне ядра:

Настройка конфигурации.

nosharepages не распределять выделенные страницы в пользу других запущенных виртуальных машин.

locked страницы, выделенные в пользу виртуальной машины, будут заблокированы для использования хостом. Чтобы вернуть память хосту, потребуется завершить работу виртуальной машины. Опция полезна для задач, выполняемых в режиме мягкого реального времени (требующих минимальных задержек прерываний).

Динамичное выделение больших страниц.

Позволяет выделять и освобождать страницы памяти на ходу, что очень полезно, если виртуальная машина используется периодически, а не регулярно.

К примеру, время от времени требуется запустить виртуальную машину, выполнить некие задачи и завершить её работу. В случае статичного выделения страниц, память не будет доступна для хоста, а с динамичным выделением можно освободить все ранее выделенные страницы, но есть важный нюанс.

Проблема может проявляться с выделением страниц объёмом на половину и более доступной памяти. Пример: всего 32 Гб, требуется выделить 8192 страницы по 2 Мб, но по факту система сможет выделить немногим более 6000.

Поэтому, если требуется гарантированное выделение страниц, его нужно осуществлять при старте системы, когда ещё нет фрагментации памяти. Такое выделение называется статичным, но о нём позже.

Проблему динамичного выделения больших страниц можно снизить следующими способами:

  1. Синхронизировать и сбросить страничный кэш, тем самым снизив фрагметацию.
  2. Попытаться выделить больше страниц, чем требуется по факту. Тем самым система будет агрессивнее выделять память, предоставив больше страниц.

Пример выделения динамичных больших страниц с синхронизацией и сбросом кэша.

Синхронизировать и сбросить кэшированные записи на накопитель:

Сбросить Page Cache, Dentry и Inode cache, что позволит выделить больше оперативной памяти в виде больших страниц:

Это не деструктивная операция. Будет сброшено лишь то, что не используется.

Скомпоновать память таким образом, чтобы свободная память была в смежных блоках, что снижает фрагментацию и позволяет выделить больше страниц:

Выделить 8192 страницы по 2 Мб, чтобы задействовать 16 Гб ОЗУ в пользу виртуальной машины:

Проверить сколько страниц было выделено фактически:

Статичное выделение больших страниц.

Чтобы избежать проблемы с не выделением всех запрашиваемых больших страниц из-за фрагментации памяти, их можно гарантированно выделить при старте хост-системы.

Выделение осуществляется через передачу значения специальному параметру ядра. Передать значение на старте системы можно посредством Grub. Для этого потребуется внести изменения в файл /etc/default/grub.

Необходимо добавить в строку GRUB_CMDLINE_LINUX_DEFAULT параметр hugepages=8192. Пример:

Затем обновить конфигурацию Grub:

Тем самым после перезагрузки системы будет выделено 8192 страницы по 2 Мб, что по итогу зарезервирует 16384 Мб оперативной памяти, но для использования хост-системой эта память будет недоступна, её сможет использовать только виртуальная машина.

По итогу выбор между динамичными и статичными большими страницами должен опираться на конкретный сценарий использования.

На этом завершается разбор основных вариантов оптимизации работы виртуальных машин с упором на виртуализацию ОС Windows 10.

В последнее время стал разбираться с виртуализацией Windows, поскольку этот мусор еще иногда требуется. Под Linux вопросов вообще не возникает, можно вообще использовать LXC, если просто что-то погонять надо, но, в целом, QEMU вполне себе работающее средство и ядерное, по сравнению с VirtualBox.

Поставил чистую винду, еще при установке задал диск VirtIO и отдал дрова с соответствующего диска (пакет в Fedora называется virtio-win.noarch : VirtIO para-virtualized drivers for Windows). После установки дал винде покопаться на прицепленном CD-ROM (образе из этого пакета), чтобы взять оттуда дрова для Balloon, сетевухи (тоже в virtio-режиме, как все рекомендуют) и поставил с него же QEMU guest, который, впрочем, у меня пока и не запустился.

Наступил на грабли почти сразу.
Как поклонник BTRFS, положил образ на эту файловую систему. Диск у меня - старенький Samsung на 1Тб, но вполне себе выдает 30Мб/сек на чтение, например. Для виртуалки бы мне вполне хватило, с учетом кеширования. Но не тут-то было. Скорость болталась около 500Кб/сек и с жуткими провалами.

Я все глаза стер об iostat, скорость маленькая, количество запросов не очень большое, около 120, очередь небольшая, сервис-тайм небольшой, но при этом винда адски тормозит. Все икает, загрузка идет минуты три. Пробовал отключать кеширование виртуалки, крутил с raw и qcow2, отключал CoW, никак.

Пришлось поверить всей той куче записей "не ставьте виртуалки на BTRFS". Хотя кто-то писал, что у него все нормально. И я знаю, почему. Положил образ виртуалки на SSD. Это просто самолет стал. Никаких тебе проседаний и приседаний. На одной SSD средней древности, SATA3, все просто летает. И суть, похоже в параллельном доступе к BTRFS. Если копировать на диск виртуалку - скорость очень хорошая. Если виртуалка работает на диске и лезет к нему в несколько потоков, все становится очень плохо, если это не SSD. Но, кризис. SSD, чтобы протирать его виндой, у меня нет.

Сделал md-raid0, нарезал туда дисков. Отформатировал в ext4, как сказано здесь, замонтировал так

Я заметил несколько статей, в которых утверждалось, что QEMU работает медленнее, чем VirtualBox (без помощи аппаратного обеспечения), но некоторым уже несколько лет, и новейшая версия, похоже, появилась в прошлом году.

  • Правда ли, что QEMU медленнее, чем VirtualBox?
  • Если так, то почему?
  • Есть ли какие-то хитрости, чтобы закрыть разрыв в производительности?

Некоторые из моих хост-систем не поддерживают аппаратную виртуализацию, поэтому мне особенно интересны советы по производительности, которые работают без модуля ядра.

Если вы говорите о виртуализации x86 на хосте x86, имейте в виду, что kqemu (старый модуль ядра ускорения для qemu) устарел. Виртуальная машина ядра (KVM) - это «путь вперед», но он работает только на хостах Linux. Гость может быть любой ОС, какой вы пожелаете, если это архитектура x86.

Кросс-архитектура, QEMU по-прежнему очень медленно; только сегодня я пытался установить последнюю версию qemu с Debian MIPS64 в гостевой системе . ее можно было использовать из терминала, но в Xorg это было ужасно медленно. Насколько мне известно, вы не можете использовать инструкции по ускорению процессора, такие как расширенные таблицы страниц или VT-x, когда вы собираетесь кросс-архитектуры. Это все эмулируется в программном обеспечении.

Таким образом, для виртуализации от x86 до x86 «сырая» qemu медленная, но KVM (которая использует qemu) быстрая. Довольно быстро. Настолько быстро, что это рекомендуемое Red Hat решение для виртуализации RHEL.

VirtualBox по-прежнему отбрасывает все, что может предложить qemu / kvm, с точки зрения производительности 2D / 3D-графики с аппаратным ускорением, поскольку kvm фокусируется на виртуализации серверов, а virtualbox - на виртуализации десктопов. Но я определенно рекомендую вам проверить kvm, если вы имеете дело с сервером.

Изменить: Для ваших хостов, которые не имеют аппаратного ускорения, вы будете страдать от довольно больших накладных расходов, независимо от того, какое решение Virt вы используете. Эмулировать аппаратные вещи в программном обеспечении сложно и дорого.

Читайте также: