Вопрос или проблема
Я запускаю виртуальную машину на RHEL9 (qemu-kvm 9.0.0, релиз 10.el9_5), и наблюдаю довольно низкую производительность ввода-вывода (примерно четверть от нативной производительности). Вот некоторые метрики, собранные с помощью fio
:
$ fio --name TEST --eta-newline=5s --filename=fio-tempfile.dat --rw=randrw --size=500m --io_size=10g --blocksize=4k --ioengine=libaio --fsync=1 --iodepth=1 --direct=1 --numjobs=1 --runtime=60 --group_reporting
В ВМ
- ЧТЕНИЕ: IOPS=506, BW=2027KiB/s
- ЗАПИСЬ: IOPS=509, BW=2017/s, средняя задержка fsync=766 наносекунд
НАТИВНЫЙ (без виртуализации)
- ЧТЕНИЕ: IOPS=1701, BW=6807KiB/s
- ЗАПИСЬ: IOPS=1693, BW=6773KiB/s, средняя задержка fsync=385 наносекунд
$ fio --name TEST --eta-newline=5s --filename=fio-tempfile.dat --rw=randrw --size=500m --io_size=10g --blocksize=4k --ioengine=libaio --fsync=1 --iodepth=128 --direct=1 --numjobs=16 --runtime=60 --group_reporting
В ВМ
- ЧТЕНИЕ: IOPS=2294, BW=9179KiB/s
- ЗАПИСЬ: IOPS=2292, BW=9168KiB/s, средняя задержка fsync=838 наносекунд
НАТИВНЫЙ
- ЧТЕНИЕ: IOPS=10.5k, BW=40.9MiB/s
- ЗАПИСЬ: IOPS=10.5k, BW=40.9MiB/s, средняя задержка fsync=338 наносекунд
Таким образом, я получаю около четверти производительности внутри ВМ по сравнению с внешней. Я ожидал падения производительности на пару процентов, возможно 10%, но не настолько — или мои ожидания просто неразумны?
Настройка следующая:
- 96 ядер (учитывая гипертрейдинг), все 96 назначены ВМ
- Настроено 16 потоков ввода-вывода
- Выделенный диск только для ВМ (диски 7.68T, SAS SSD)
- Диски являются многопутевыми и зашифрованы с помощью LUKS (расшифровываются на хост-машине, после чего устройство /dev/mapper/… отправляется в ВМ)
- Диск в libvirt настроен как type=”raw”, cache=”none”, io=’native’, queues=”8″, queue_size=”1024″ (эти значения, конечно, немного произвольны, но именно к этому я пришел в поисках повышения производительности до сих пор) шина bus=”virtio”
- Я использую libvirt 10.5.0 и создаю ВМ с помощью virt-install
- Внутри ВМ я в настоящее время запускаю CentOS 7 (да, очень устаревший, но поскольку у нас есть МНОГО ВМ, которые нужно мигрировать, это медленный процесс, и кластер Hadoop получает короткую часть этой палки…)
В данный момент я, в основном, ищу альтернативные идеи относительно того, что может снижать мою производительность — может ли быть так, что я использую LUKS и многопути за пределами ВМ, а не внутри? Или что мне следует использовать больше или меньше очередей/глубины очереди? Или другой движок ввода-вывода? Стоит ли попробовать сравнить virtio-scsi и virtio-blk?
Я также рассматривал возможность попробовать PCI-прямую передачу, но поскольку контроллер SCSI управляет несколькими дисками (аппаратное обеспечение HPE synergy), я не могу легко это сделать, не отдав все диски ВМ.
В конечном итоге, что я хочу запустить внутри этих ВМ, это задания spark + HDFS, так что это довольно ресурсоемкие приложения для диска.
Ответ или решение
Краткое введение: оптимизация I/O производительности в виртуальных машинах
Вы столкнулись с серьезной проблемой производительности ввода-вывода (I/O) при работе с виртуальной машиной на RHEL9 с использованием qemu-kvm. Производительность в вашей среде виртуализации составляет около четверти от производительности на «железе», что, безусловно, вызывает беспокойство. Данная статья предложит ряд рекомендаций для повышения I/O производительности и поможет вам понять причины, по которым вы наблюдаете такие низкие показатели.
Обзор проблемы
Судя по вашим тестам с использованием fio
, вы наблюдаете следующее:
-
Внутри VM (виртуальной машины):
- Чтение: IOPS=506, BW=2027KiB/s
- Запись: IOPS=509, BW=2017KiB/s
-
Непосредственно на хосте:
- Чтение: IOPS=1701, BW=6807KiB/s
- Запись: IOPS=1693, BW=6773KiB/s
Ваши выводы о потере производительности на уровне 75% действительно нашли подтверждение в представленных данных. Давайте рассмотрим возможные причины и решения.
Возможные причины низкой производительности
-
Конфигурация устройств I/O:
- Использование
virtio
для виртуальных устройств — это правильный выбор, но вам стоит протестировать и альтернативные варианты, такие какvirtio-scsi
. В некоторых случаяхvirtio-scsi
может предоставить лучшую производительность ввода-вывода для тяжелых дисковых операций.
- Использование
-
Параметры кэширования и I/O:
- Вы указали
cache="none"
иio='native'
. Хотя это может предоставить некоторые преимущества в случае использования дисков с низкой задержкой, попробуйте параметрыcache="writeback"
для выявления потенциальной выгоды. Обратите внимание, что это может привести к утечкам данных при сбоях питания, и его использование нужно оценивать в зависимости от требований к доступности данных.
- Вы указали
-
Скорость множества потоков (iothreads):
- У вас настроено 16 потоков I/O, что для многих сценариев может оказывать положительное влияние. Попробуйте увеличить количество потоков, или, наоборот, протестируйте падение производительности при уменьшении их числа, чтобы найти оптимальное значение.
-
Ширина очереди и размер очереди:
- Попробуйте увеличить параметры
queues
иqueue_size
. Исследуйте параметры до 64 и 8192 соответственно, чтобы максимально использовать параллелизм вашей системы, особенно с 96 ядрами.
- Попробуйте увеличить параметры
-
Шифрование LUKS:
- Хотя шифрование является важным аспектом безопасности, его использование может негативно сказаться на производительности. Попробуйте протестировать производительность без шифрования, чтобы понять, как это влияет на I/O. Также важно учесть, что шифрование на хосте обрабатывается более эффективно, чем внутри VM.
-
Параметры
fio
:- Обратите внимание на
iodepth
, увеличив его с 1 до 128 при тестировании, вы уже понизили показатели замедления. С значениямиnumjobs=16
, это позволяет вашей виртуальной машине максимизировать использование многопоточности.
- Обратите внимание на
Рекомендации по улучшению производительности
-
Проведение тестов с различными конфигурациями:
- Проведите последовательные тесты с различными настройками
virtio
и параметрами устройства. Сравните производительность междуvirtio-blk
иvirtio-scsi
.
- Проведите последовательные тесты с различными настройками
-
Запуск внешних тестов производительности:
- Проведите тесты без виртуальной машины на сервере, подключите его к помимо внутреннего хранилища, чтобы исключить возможные проблемы с дисковыми подсистемами.
-
Тестирование при отключенном шифровании:
- Временное отключение LUKS для проверки I/O-производительности обеспечит вам более ясную картины.
-
Оптимизация системных параметров:
- Проверьте конфигурацию вашего хранилища и операционной системы, удостоверьтесь, что параметры планировщика I/O соответствуют вашему типу рабочей нагрузки.
-
Использование PCI-проигрывателя:
- Если ваша инфраструктура это позволяет, тестирование с использованием PCI-проигрывателя для определенных устройств может дать вам возможность обойти некоторые ограничения виртуализации.
Заключение
Оптимизация производительности I/O в виртуальных машинах — задача, которая требует многогранного подхода. Обеспечение правильной конфигурации, проведении тестирования различных параметров и использование современных возможностей вашего оборудования позволит вам достичь значительного повышения производительности. Не забывайте о важности грамотной диагностики и тестирования, чтобы понять реальные узкие места вашего хранилища и виртуализации.