Async IO в Proxmox: настройка и диагностика производительности дисков

Медленный ввод-вывод внутри виртуальной машины Proxmox — один из самых частых поводов для настройки параметра IO Thread и экспериментов с асинхронным вводом-выводом: гостевая система показывает высокую задержку диска, команда iostat на хосте фиксирует рост await, а приложения в ВМ начинают тормозить под нагрузкой. В большинстве таких случаев проблема связана с тем, как QEMU обрабатывает дисковые запросы — синхронно или через механизм io_uring, и какой режим кэширования выбран для виртуального диска.

Proxmox VE построен на связке KVM + QEMU, и именно QEMU отвечает за обработку запросов ввода-вывода виртуальных машин. Понимание того, как работает асинхронный ввод-вывод (async IO) в этой связке, позволяет осознанно выбирать настройки диска, а не перебирать их наугад. Ниже разберём принципы работы, доступные режимы и безопасную диагностику.

Что такое async IO в контексте Proxmox и QEMU

Под асинхронным вводом-выводом в Proxmox обычно понимают механизм io_uring — интерфейс ядра Linux, который позволяет приложению отправлять операции чтения и записи без блокировки потока на время их выполнения. QEMU может использовать io_uring как асинхронный движок (AIO engine) для обработки дисковых запросов виртуальных машин.

Альтернативные движки — threads (пул потоков, эмулирующий асинхронность) и native (классический Linux AIO). Выбор движка влияет на задержки, нагрузку на процессор хоста и поведение под параллельной нагрузкой от нескольких ВМ.

Важно различать два разных уровня настройки:

  • ⚙️ AIO-движок QEMU — как именно эмулятор выполняет дисковые операции (io_uring, threads, native);
  • 🧵 IO Thread — выделенный поток virtio-контроллера, обрабатывающий ввод-вывод отдельно от основного потока ВМ;
  • 💾 Режим кэша — как хост кэширует записи гостевой системы (writeback, writethrough, none, directsync);
  • 📀 Тип хранилища — локальный LVM, ZFS, Ceph, NFS или файл-образ qcow2/raw.

Как io_uring работает в связке с QEMU

Механизм io_uring появился в ядре Linux как современная замена старому интерфейсу AIO. Его ключевая идея — кольцевые буферы, разделяемые между ядром и приложением: QEMU помещает запросы в очередь отправки и забирает результаты из очереди завершения без лишних системных вызовов на каждую операцию.

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

Однако io_uring не является универсально лучшим вариантом. На отдельных комбинациях «версия ядра + тип хранилища» возможны особенности поведения, поэтому перед переводом продуктивных машин на новый движок стоит провести нагрузочное тестирование на тестовой ВМ с похожим профилем нагрузки.

Настройка диска ВМ: IO Thread, кэш и движок AIO

Основные параметры, влияющие на асинхронную обработку ввода-вывода, задаются в свойствах диска виртуальной машины: Hardware → Hard Disk → Edit. Там же включается опция IO Thread, которая выносит обработку запросов virtio-диска в отдельный поток QEMU.

Режим кэширования выбирается в поле Cache. Каждый вариант имеет свои компромиссы между скоростью и надёжностью:

Режим кэшаПринцип работыКогда уместен
noneЗапросы идут мимо страничного кэша хостаХранилища с собственным кэшированием, экономия RAM хоста
writebackЗапись подтверждается после попадания в кэш хостаМаксимальная скорость, приемлем риск потери данных при сбое питания
writethroughЗапись подтверждается после физической записи на дискБаланс надёжности и скорости чтения
directsyncБез кэша хоста, каждая запись сбрасывается на носительКритичные данные, где важна долговечность каждой транзакции
⚠️ Внимание: режим writeback ускоряет запись, но при внезапном отключении питания хоста данные, находившиеся только в кэше, могут быть потеряны, а файловая система гостя — повреждена. Для продуктивных баз данных оцените этот риск заранее и обеспечьте резервное копирование.

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

☑️ Настройка async IO для диска ВМ

Выполнено: 0 / 5
📊 Какой режим кэша вы используете для дисков ВМ в Proxmox?
none
writeback
writethrough
directsync

Диагностика медленного ввода-вывода на хосте

Прежде чем менять настройки async IO, необходимо убедиться, что узкое место действительно находится на уровне обработки запросов QEMU, а не на уровне физического хранилища или сети. Симптомы вроде «высокий load average при низком CPU» часто указывают именно на ожидание диска.

Начните с наблюдения за хостом во время нагрузки внутри ВМ:

iostat -x 2

Обратите внимание на столбцы await (средняя задержка операции) и %util (загруженность устройства). Если %util физического диска близок к максимуму, а задержки растут — упор идёт в сам носитель, и никакая настройка AIO-движка это не исправит принципиально.

Внутри гостевой системы полезно проверить задержки теми же средствами: высокий await в госте при спокойном хосте косвенно указывает на прослойку виртуализации — тогда есть смысл экспериментировать с IO Thread и кэшем.

  • 🔍 Высокий await и на хосте, и в госте — вероятен предел производительности самого хранилища;
  • 🔍 Высокий await только в госте — стоит проверить настройки диска ВМ и включён ли IO Thread;
  • 🔍 Высокий iowait при множестве ВМ — возможна конкуренция за общее хранилище, поможет распределение дисков;
  • 🔍 Проблемы только на сетевом хранилище — проверяйте сеть и настройки NFS/Ceph, а не AIO-движок.
Чем измерить диск внутри ВМ

Для грубой оценки используют fio с типовыми профилями (случайное чтение/запись блоками 4k, глубина очереди 32). Запускайте тест на тестовом разделе: fio разрушительно записывает данные при тестах записи. Сравнивайте результаты до и после смены настроек — важна динамика, а не абсолютные цифры.

Типичные ошибки при настройке async IO

Одна из распространённых ошибок — менять сразу несколько параметров: включить IO Thread, сменить кэш и переключить формат диска за один раз. В этом случае невозможно понять, какое изменение дало эффект, а какое ухудшило ситуацию. Меняйте настройки по одной и измеряйте результат после каждой.

Вторая ошибка — ожидать чуда от настроек при слабом физическом хранилище. Никакой AIO-движок не сделает одиночный SATA-диск быстрым для десятка одновременно работающих ВМ — асинхронность оптимизирует обработку запросов, но не увеличивает пропускную способность носителя.

⚠️ Внимание: включение IO Thread для диска на контроллере, отличном от virtio (например, IDE или SATA в режиме эмуляции), может не дать ожидаемого эффекта. Опция рассчитана прежде всего на virtio-устройства — проверьте тип контроллера диска в настройках ВМ.

Третья ошибка — копирование чужих «оптимальных» конфигураций без учёта собственного стека. Поведение кэша и io_uring различается для ZFS, Ceph, LVM-thin и файловых образов, поэтому рекомендации, собранные для чужой инфраструктуры, требуют проверки на вашей.

Влияние типа хранилища на поведение async IO

На локальных хранилищах вроде LVM-thin или ZFS асинхронная обработка запросов работает напрямую с блочным устройством, и эффект от io_uring и IO Thread обычно наиболее заметен. На ZFS дополнительно влияет собственный механизм кэширования ARC и группировка записей в транзакции.

На сетевых хранилищах (NFS, Ceph RBD) картина иная: значительная часть задержки формируется сетью и удалённым кластером. Настройки кэша на стороне QEMU здесь по-прежнему важны, но диагностику следует начинать с проверки сетевых задержек и состояния кластера хранения.

Для файловых образов дисков учитывайте разницу форматов: raw работает напрямую с данными, а qcow2 добавляет слой преобразования адресов и поддержку снапшотов ценой дополнительных операций. На нагруженных системах это различие может быть ощутимым.

FAQ: частые вопросы об async IO в Proxmox

Что даёт включение IO Thread для диска ВМ?

Опция выносит обработку ввода-вывода virtio-диска в отдельный поток QEMU, что снижает конкуренцию с основным потоком эмуляции ВМ. На нагруженных машинах это может уменьшить задержки диска и сгладить просадки производительности.

Какой режим кэша выбрать для базы данных в ВМ?

Универсального ответа нет: writethrough и directsync надёжнее при сбоях питания, writeback быстрее, но рискованнее. Проверьте, есть ли у хоста источник бесперебойного питания и настроены ли регулярные бэкапы, и выбирайте исходя из допустимого риска потери данных.

Почему после включения async IO производительность не выросла?

Возможная причина — узкое место находится не в обработке запросов QEMU, а в самом хранилище или сети. Проверьте iostat -x на хосте: если физическое устройство загружено на пределе, требуется апгрейд хранилища или перераспределение ВМ, а не настройка движка.

Нужно ли перезагружать ВМ после смены настроек диска?

Да, параметры диска (IO Thread, режим кэша) применяются при запуске виртуальной машины. Гостевую систему следует корректно выключить и запустить заново — простая перезагрузка изнутри гостя не всегда пересоздаёт конфигурацию устройства.

Опасно ли менять настройки диска на продуктивной ВМ?

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