zVirt 4.2: тестируем live migration с NUMA и разбираемся, что меняется для maintenance-окон
zVirt 4.2 вышел с улучшенной live migration и CPU hotplug. Тестируем на стенде с NUMA-топологией: пауза гостя при миграции наконец стала предсказуемой.
Релиз zVirt 4.2 с улучшенной live migration и поддержкой CPU hotplug
zVirt 4.2 вышел в середине января. Главное, что нас интересовало в changelog - два пункта: переработанная live migration для ВМ с NUMA-топологией и CPU hotplug. Подняли на тестовом кластере, воспроизвели сценарий, который в 4.1 вызывал устойчивую головную боль - и вот что получилось.
Проблема, которую мы ждали когда починят
В zVirt 4.1 мы отмечали, что планировщик стал умнее и лишних миграций поубавилось. Но сама механика live migration для ВМ с NUMA-topology binding оставалась болезненной точкой.
Суть проблемы: если ВМ запущена с явной привязкой к NUMA-узлу (numa_tune в libvirt/QEMU - mode="strict" или mode="preferred"), то при live migration движок должен найти на целевом хосте подходящий NUMA-узел с аналогичной топологией и свободными ресурсами. В 4.1 это работало, но с заметной паузой гостя в момент финального переключения - у нас она стабильно уходила в несколько секунд на ВМ с большим объёмом памяти. Для СУБД это означало: берёшь maintenance-окно, закладываешь туда не только время миграции, но и время, пока PostgreSQL отойдёт от freeze, отдышится и вернётся в нормальный ритм репликации.
Что изменилось в 4.2
В release notes zVirt 4.2 по этому пункту написано кратко - «improved NUMA-aware migration scheduling». На практике это означает, что предварительный расчёт целевого NUMA-узла теперь происходит до начала итеративной передачи памяти, а не в последний момент перед финальным стопом гостя.
На нашем тестовом стенде - три хоста с двумя NUMA-узлами каждый, ВМ от 32 до 128 ГБ RAM с numa_tune strict - картина изменилась ощутимо. Финальная пауза гостя, которая в 4.1 была нестабильной и зависела от того, насколько быстро движок «разбирался» с NUMA-маппингом на целевом хосте, в 4.2 стала короткой и предсказуемой. Насколько короткой - зависит от конкретного железа и нагрузки, но важен сам факт предсказуемости: теперь поведение воспроизводится стабильно от миграции к миграции.
Это не магия - это просто правильный порядок операций, который наконец реализовали.
CPU hotplug: пробуем осторожно
Второй анонсированный пункт - CPU hotplug, то есть возможность добавить vCPU работающей ВМ без перезагрузки. Функция не новая для индустрии, но в zVirt её до этого не было.
Попробовали на тестовой ВМ с Astra Linux SE 1.8 в качестве гостя. Механика работает: добавляем vCPU через Engine, ОС видит новые процессоры, задействует их. Но с оговорками.
Первая: ядро гостя должно поддерживать cpu_hotplug. В современных ядрах Astra Linux SE 1.8 поддержка есть, но нужно убедиться, что в конфигурации ядра это явно включено. В нашем тестовом гостевом образе - включено, проблем не было.
Вторая: hotplug работает только на увеличение количества vCPU. Убрать vCPU обратно без перезагрузки - нельзя. Это ограничение QEMU-уровня, не специфика zVirt.
Третья: если ВМ запущена с NUMA-topology binding, увеличение vCPU требует, чтобы новые ядра помещались в ту же NUMA-топологию. Иначе Engine отказывает с ошибкой. Это разумное ограничение, но нужно держать в голове при планировании ёмкости.
Для maintenance-сценариев CPU hotplug скорее дополнительный инструмент, чем основной. Основной - всё-таки live migration.
Что это меняет для планирования maintenance-окон
Главный практический вывод из тестирования: окна для плановых работ на production-хостах становятся более предсказуемыми.
Раньше при планировании обслуживания хоста (обновление firmware, ядра хостовой ОС) мы закладывали буфер на «непредсказуемое поведение» NUMA-ВМ при миграции. Это значило: или выбирать окно с запасом и заранее предупреждать клиента о более длинном обслуживании, или идти на риск пропустить окно из-за затянувшейся миграции. Ни то ни другое - не подарок.
С предсказуемой паузой появляется возможность нормально рассчитывать время окна. Не «три часа на всякий случай», а обоснованный расчёт: сколько ВМ, сколько памяти, сколько занимает итеративная передача на нашем сетевом стыке между хостами - и добавить понятный, воспроизводимый overhead на финальное переключение.
На практике это в первую очередь влияет на managed-сопровождение кластеров с плотной NUMA-нагрузкой - там, где несколько ВМ СУБД или аналитических движков сидят с явной топологией памяти.
Где сейчас
Тестовый стенд поработал несколько дней, ничего экстраординарного не вылезло. Обновление на production-кластеры клиентов запланировали после того, как немного отлежится и не появится фиксирующих patching notes от вендора - это наша стандартная выдержка для минорных релизов.
Один вопрос остаётся открытым: как NUMA-aware migration поведёт себя на хостах с неоднородной NUMA-конфигурацией - например, когда NUMA-узлы разного объёма. В тестовом стенде у нас симметричная топология. Асимметричную не проверяли, держим в списке.