Плохая производительность ввода-вывода с qemu-kvm и родным блочным устройством (выделенный диск)

Вопрос или проблема

Я запускаю виртуальную машину на 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% действительно нашли подтверждение в представленных данных. Давайте рассмотрим возможные причины и решения.

Возможные причины низкой производительности

  1. Конфигурация устройств I/O:

    • Использование virtio для виртуальных устройств — это правильный выбор, но вам стоит протестировать и альтернативные варианты, такие как virtio-scsi. В некоторых случаях virtio-scsi может предоставить лучшую производительность ввода-вывода для тяжелых дисковых операций.
  2. Параметры кэширования и I/O:

    • Вы указали cache="none" и io='native'. Хотя это может предоставить некоторые преимущества в случае использования дисков с низкой задержкой, попробуйте параметры cache="writeback" для выявления потенциальной выгоды. Обратите внимание, что это может привести к утечкам данных при сбоях питания, и его использование нужно оценивать в зависимости от требований к доступности данных.
  3. Скорость множества потоков (iothreads):

    • У вас настроено 16 потоков I/O, что для многих сценариев может оказывать положительное влияние. Попробуйте увеличить количество потоков, или, наоборот, протестируйте падение производительности при уменьшении их числа, чтобы найти оптимальное значение.
  4. Ширина очереди и размер очереди:

    • Попробуйте увеличить параметры queues и queue_size. Исследуйте параметры до 64 и 8192 соответственно, чтобы максимально использовать параллелизм вашей системы, особенно с 96 ядрами.
  5. Шифрование LUKS:

    • Хотя шифрование является важным аспектом безопасности, его использование может негативно сказаться на производительности. Попробуйте протестировать производительность без шифрования, чтобы понять, как это влияет на I/O. Также важно учесть, что шифрование на хосте обрабатывается более эффективно, чем внутри VM.
  6. Параметры fio:

    • Обратите внимание на iodepth, увеличив его с 1 до 128 при тестировании, вы уже понизили показатели замедления. С значениями numjobs=16, это позволяет вашей виртуальной машине максимизировать использование многопоточности.

Рекомендации по улучшению производительности

  1. Проведение тестов с различными конфигурациями:

    • Проведите последовательные тесты с различными настройками virtio и параметрами устройства. Сравните производительность между virtio-blk и virtio-scsi.
  2. Запуск внешних тестов производительности:

    • Проведите тесты без виртуальной машины на сервере, подключите его к помимо внутреннего хранилища, чтобы исключить возможные проблемы с дисковыми подсистемами.
  3. Тестирование при отключенном шифровании:

    • Временное отключение LUKS для проверки I/O-производительности обеспечит вам более ясную картины.
  4. Оптимизация системных параметров:

    • Проверьте конфигурацию вашего хранилища и операционной системы, удостоверьтесь, что параметры планировщика I/O соответствуют вашему типу рабочей нагрузки.
  5. Использование PCI-проигрывателя:

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

Заключение

Оптимизация производительности I/O в виртуальных машинах — задача, которая требует многогранного подхода. Обеспечение правильной конфигурации, проведении тестирования различных параметров и использование современных возможностей вашего оборудования позволит вам достичь значительного повышения производительности. Не забывайте о важности грамотной диагностики и тестирования, чтобы понять реальные узкие места вашего хранилища и виртуализации.

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

Капча загружается...