ZIM-НИЙ SAAALEЗимние скидки: до −50% на старт и −20% на продление
до 31.01.2026 Подробнее
Выберите продукт

KVM/QEMU: virtio и tuned — практический тюнинг производительности и latency

Пошагово разбираем, как ускорить KVM/QEMU на Linux-хосте: проверить virtio-устройства, включить multiqueue на virtio-net, подобрать offload, снизить disk latency через правильный стек и очереди, применить tuned profile и дойти до CPU pinning/NUMA/IRQ-affinity.
KVM/QEMU: virtio и tuned — практический тюнинг производительности и latency

Зачем тюнить virtio в KVM/QEMU

KVM/QEMU давно перестали быть историей про «запустили VM и забыли». В продакшене производительность часто упирается в детали: очереди virtio, количество vCPU у гостя, модель диска (virtio-blk или virtio-scsi), раскладку прерываний, сетевые offload’ы и то, как хостовое ядро управляет энергосбережением и планировщиком.

Хорошая новость: большинство улучшений делаются без «магии» и почти всегда проверяются метриками. Плохая: один неудачный флажок легко добавляет миллисекунды к хвостам (p99) или режет пропускную способность вдвое.

Дальше разберём типовой стек: Linux-хост с KVM/QEMU, Linux-гость, устройства virtio-net и virtio-blk/virtio-scsi, системный тюнинг через tuned. Я буду говорить «хост» — это ОС с qemu-kvm, «гость» — виртуальная машина.

Где прячется latency: virtqueue, IRQ, offload, I/O и CPU

virtio — семейство паравиртуальных устройств: вместо эмуляции железа (e1000/ide/lsi) гость и хост обмениваются дескрипторами через virtqueue. Это снижает накладные расходы, но создаёт несколько типовых точек, где легко потерять производительность или предсказуемость задержек.

  • Очереди (multiqueue): мало очередей — упираетесь в одно ядро; слишком много — растёт overhead и шанс IRQ-«снега».
  • Прерывания и affinity: плохая раскладка IRQ/vCPU даёт миграции кэшей и очереди в softirq.
  • Сетевые offload’ы (GSO/TSO/GRO/CSUM): экономят CPU на throughput, но могут ухудшать tail latency на мелких RPC.
  • Дисковый стек: модель устройства, iothread, режимы кэша, I/O-планировщик на хосте/госте.
  • Энергосбережение: governor, C-states, jitter от частот и пробуждений.

Практика почти всегда одна: сначала фиксируем baseline, затем включаем правильные устройства/очереди, после — приводим в порядок CPU/IRQ и только потом идём в pinning/NUMA.

Проверка multiqueue и распределения прерываний virtio-net в Linux

Минимальные проверки: что у вас сейчас и где узкое место

Перед любым тюнингом зафиксируйте исходные показатели: disk latency/IOPS, сетевой throughput, а также загрузку CPU и перекосы по softirq. Без этого вы не поймёте, стало ли лучше.

Понять, какие устройства у гостя

Внутри гостя:

lsblk -o NAME,TYPE,SIZE,MODEL
lspci -nn | grep -i virtio
ethtool -i eth0

Для сети вы хотите видеть драйвер virtio_net. Для дисков — virtio-модель (обычно vda для virtio-blk или SCSI-слой при virtio-scsi).

Быстрые метрики по хосту

uptime
vmstat 1 10
mpstat -P ALL 1 5
pidstat -t -p $(pidof qemu-system-x86_64) 1 5

Если видите swap (рост si/so), высокий iowait или один CPU забит softirq — тюнинг будет разным: где-то нужно больше очередей, где-то — меньше агрегации или жёстче раскладывать IRQ.

Замер дисковой latency/IOPS (fio)

Внутри гостя (на проде аккуратно: лучше на тестовом файле/томе):

fio --name=randread --filename=/var/tmp/fio.test --size=2G --direct=1 --ioengine=libaio --iodepth=32 --rw=randread --bs=4k --numjobs=4 --time_based --runtime=60 --group_reporting

Смотрите не только среднюю задержку, но и хвосты (p95/p99). Для баз данных и очередей это зачастую важнее максимальных IOPS.

Замер сети (идея)

Для throughput по сети обычно используют iperf3 между двумя VM/хостами в одном сегменте. Для задержек — отдельно измеряйте ping и «прикладную» latency (например, ответ вашего API), потому что хорошая полоса не гарантирует хороший p99.

FastFox VDS
Облачный VDS-сервер в России
Аренда виртуальных серверов с моментальным развертыванием инфраструктуры от 195₽ / мес

virtio-net: multiqueue, offload и IRQ — где чаще всего теряется скорость

virtio-net почти всегда правильный выбор. Но «по умолчанию» вы можете не получить многопоточность: один RX/TX queue упрётся в одно ядро и станет лимитом по PPS/throughput.

Проверяем и включаем multiqueue (гость)

Смотрим, сколько каналов доступно:

ethtool -l eth0

Если сейчас один канал, пробуем увеличить (если драйвер/устройство поддерживает):

ethtool -L eth0 combined 4

Практическое правило: начните с combined = min(vCPU, 4..8). Для маленьких VM (2–4 vCPU) обычно 2–4 очереди дают максимум эффекта без лишнего overhead.

RPS/RFS и softirq: когда multiqueue нет или его мало

Если по архитектуре очередей мало, иногда помогает распределить обработку пакетов через RPS/RFS. Это не замена multiqueue, но может выровнять нагрузку.

Типовой признак проблемы: один CPU забит ksoftirqd, остальные простаивают. Для диагностики:

cat /proc/interrupts | head
cat /proc/net/softnet_stat | head

Если видите явный перекос, дальше логично либо включать multiqueue на устройстве, либо настраивать affinity IRQ и/или RPS (в зависимости от вашей схемы сети и версии ядра).

Offload’ы virtio-net: throughput vs tail latency

Offload’ы обычно включены и экономят CPU на больших потоках. Но для низких задержек (мелкие RPC, очереди, чаты, real-time обработка) иногда полезно отключить часть агрегации и проверить хвосты.

Текущие флаги:

ethtool -k eth0

Кандидаты для A/B-теста:

ethtool -K eth0 gro off gso off tso off

Это не универсальная рекомендация. Отключая GRO/GSO/TSO, вы часто снижаете throughput и повышаете CPU. Делайте сравнение на одинаковой нагрузке и обязательно фиксируйте p95/p99.

virtio-blk vs virtio-scsi: что выбрать и как снизить disk latency

Если нужен «простой и быстрый» диск — virtio-blk часто отлично подходит. Если нужна гибкость (hotplug, сложные конфигурации, больше возможностей на уровне SCSI) — выбирают virtio-scsi. На практике разница часто меньше, чем влияние CPU/IRQ/NUMA и режима работы хранилища на хосте.

Проверьте планировщик I/O в госте

В госте:

lsmod | grep -E 'virtio|scsi'
cat /sys/block/vda/queue/scheduler 2>/dev/null
cat /sys/block/sda/queue/scheduler 2>/dev/null

На современных ядрах для виртуальных дисков обычно разумны none или mq-deadline (зависит от версии ядра и типа backend-хранилища). Если видите «странные» или очень старые значения, иногда дешевле обновить ядро/дистрибутив, чем бесконечно подкручивать параметры вокруг устаревшего стека.

Не путайте «быстро» и «много»: iodepth/numjobs и хвосты

Синтетика с большим iodepth легко рисует красивые IOPS, но p99 latency при этом может стать неприемлемым. Это не «обман», а реальная характеристика очередей и конкуренции за ресурсы.

Для сравнения делайте минимум два профиля тестов:

  • latency-oriented: iodepth=1..4, небольшие блоки, умеренное число потоков;
  • throughput-oriented: iodepth=16..64, больше параллелизма.

Кэширование QEMU и writeback: осторожно

Режимы кэша диска задаются на хосте (libvirt XML или параметры QEMU). Неправильный режим может ускорить «цифры» в бенчмарке, но ухудшить надёжность и поведение при авариях.

Если вы не уверены, какой режим кэша безопасен именно для вашей схемы хранения, держитесь консервативных настроек и сначала обеспечьте корректную модель записи (fsync/барьеры/гарантии backend), а уже потом оптимизируйте производительность.

Во многих реальных случаях больший эффект дают не кэш-флаги, а: правильное распределение CPU/IRQ, настройка очередей и адекватный системный профиль на хосте.

Вывод fio с percentiles задержек (p95/p99) для оценки disk latency в VM

tuned: как выбрать профиль под производительность и latency

tuned — менеджер профилей производительности в Linux. Он меняет governor CPU, параметры энергосбережения, sysctl и ряд опций, влияющих на задержки и throughput. Практическая ценность tuned в том, что вы можете быстро переключиться между профилями и сравнить результат измерениями.

Установка и базовые команды

tuned-adm --version
tuned-adm list
tuned-adm active

Типовая логика выбора профиля:

  • Если важнее максимальная пропускная способность и «ровная» загрузка — часто подходит throughput-performance.
  • Если VM latency-sensitive (БД, очереди, API) — попробуйте latency-performance.
  • На выделенных хостах под виртуализацию в некоторых дистрибутивах встречается профиль уровня virtual-host (название зависит от поставщика).

Применение:

tuned-adm profile latency-performance
tuned-adm active

После переключения обязательно повторите ваши тесты. «На глаз» в теме latency почти всегда ошибочно.

Что в tuned обычно влияет сильнее всего

  • CPU governor: перевод в performance и отказ от агрессивного power saving.
  • Параметры энергосбережения: влияние C-states на wakeup latency.
  • Сетевые sysctl: backlog/буферы и связанные параметры, влияющие на поведение под нагрузкой.

Если хвосты стали лучше, но выросло потребление энергии и средняя загрузка CPU — это типичный компромисс «latency vs efficiency».

Если упираетесь в лимиты CPU/памяти на сервисах внутри VM, проверьте ещё и ограничения systemd: иногда «медленный QEMU» на деле оказывается лимитом cgroups для процесса сервиса. См. материал про лимиты CPU/памяти в systemd.

Виртуальный хостинг FastFox
Виртуальный хостинг для сайтов
Универсальное решение для создания и размещения сайтов любой сложности в Интернете от 95₽ / мес

CPU pinning, NUMA и раскладка IRQ: когда нужны «взрослые» меры

Если вы уже включили virtio, настроили очереди и подобрали tuned, а latency всё ещё «плавает», часто виноваты миграции vCPU по ядрам, конкуренция с другими задачами на хосте и NUMA-эффекты.

Проверяем NUMA на хосте

lscpu | grep -E 'NUMA|Socket|CPU\(s\)'
numactl --hardware

Если хост NUMA, старайтесь держать vCPU и память VM в пределах одного NUMA-узла (особенно для баз данных). Иначе получите непредсказуемые хвосты из-за удалённой памяти.

Идея pinning: меньше миграций — стабильнее p99

Pinning (закрепление vCPU за физическими CPU) и изоляция ядер под VM уменьшают jitter. Это особенно заметно на высоких PPS/IOPS и при «шумных соседях» на хосте.

Реализация зависит от стека управления (libvirt или чистый QEMU), но цель одна: vCPU, IRQ virtio и (если используете) iothread’ы должны быть распределены осмысленно, а не оставлены на усмотрение планировщика.

Прерывания virtio: почему важен affinity

Даже если у VM 8 vCPU, но все IRQ virtio-net обрабатываются на одном ядре, вы снова получите узкое место. Смотрите /proc/interrupts и настраивайте affinity вручную или через связку irqbalance/tuned (в зависимости от политики на хосте).

Практический сценарий тюнинга: от простого к сложному

  1. Фиксируем baseline: fio (диск), сетевые тесты (throughput и latency), CPU/softirq на хосте.

  2. Проверяем устройства: сеть — virtio-net, диски — virtio-blk или virtio-scsi (не e1000/ide).

  3. Включаем multiqueue для virtio-net и проверяем, что нагрузка распределилась по ядрам.

  4. Тестируем offload’ы: сначала дефолт, затем точечно отключаем GRO/GSO/TSO, если цель — минимальные хвосты.

  5. Переключаем tuned на хосте: сравниваем throughput-performance и latency-performance под вашей нагрузкой.

  6. Если хвосты всё ещё плохие: pinning/NUMA/IRQ-affinity, устранение миграций и конкуренции.

Типовые симптомы и быстрые подсказки

Throughput низкий, CPU свободен

Проверьте multiqueue у virtio-net, не упираетесь ли в single queue, и как распределены IRQ. Часто решение — добавить очереди и правильно разложить прерывания.

Throughput высокий, но p99 latency плохой

Ищите агрегацию пакетов (GRO/GSO), энергосбережение CPU, миграции vCPU, NUMA-эффекты. Уменьшайте «очереди ради очередей»: слишком большой iodepth и слишком много очередей тоже добавляют хвосты.

Всплески задержек «ни с того ни с сего»

Проверьте фоновые задачи на хосте: backup/trim, kswapd и давление памяти, периодические джобы. Иногда проблема не в virtio, а в общей конкуренции за ресурсы — и тогда полезно вернуться к основам выбора конфигурации VDS/хоста (CPU/RAM/диск) и «не экономить на базовом». См. как подобрать план VDS по CPU и RAM.

Контрольный список «хорошей практики»

  • virtio везде: сеть — virtio-net, диски — virtio-blk или virtio-scsi по задаче.

  • Очереди соразмерны CPU: multiqueue не должен быть «максимальным просто потому что можно».

  • tuned включён осмысленно: выбирайте профиль под задачу и подтверждайте тестами.

  • Метрики важнее ощущений: p95/p99 latency, softirq, iowait, распределение IRQ.

  • Стабильность важнее пиков: для БД и API лучше чуть меньше IOPS, но предсказуемая задержка.

Заключение

Тюнинг KVM/QEMU — это управление очередями, прерываниями и политиками CPU/энергосбережения. Начните с очевидного: virtio-net и virtio-blk/virtio-scsi, затем включите multiqueue и подберите профиль tuned. Если tail latency всё ещё страдает — переходите к pinning/NUMA/IRQ-affinity и повторяйте тесты до стабильного результата.

Если вы выбираете площадку под виртуализацию, где важны предсказуемые хвосты и контроль ресурсов, чаще всего удобнее стартовать с изолированного VDS, а не с «общей кухни». Так проще закреплять CPU, понимать I/O и стабилизировать latency под вашей нагрузкой.

Поделиться статьей

Вам будет интересно

Nginx proxy_cache for static: S3 origin, revalidation, cache lock OpenAI Статья написана AI (GPT 5)

Nginx proxy_cache for static: S3 origin, revalidation, cache lock

Пошагово настраиваем Nginx как edge‑кэш для статики с origin в S3: proxy_cache_path и cache key, revalidation через ETag/Last-Modi ...
WP-CLI: смена URL в WordPress после миграции, правка двойных слешей, проверка cron и diagnose OpenAI Статья написана AI (GPT 5)

WP-CLI: смена URL в WordPress после миграции, правка двойных слешей, проверка cron и diagnose

После переноса WordPress чаще ломаются не PHP и не веб-сервер, а данные: в базе остаются старые URL, абсолютные ссылки и «кривые» ...
nftables IPv6 firewall: правильный ICMPv6 и Neighbor Discovery без потери сети OpenAI Статья написана AI (GPT 5)

nftables IPv6 firewall: правильный ICMPv6 и Neighbor Discovery без потери сети

IPv6 чаще «падает» не из‑за адресов, а из‑за слишком строгого firewall: блокируют ICMPv6 и ломают Neighbor Discovery, SLAAC и PMTU ...