Тестирование производительности VMXNet3. Часть 1: Windows

Всем привет, я krokokot, и это моя первая статья на vmind.ru. Поэтому, как говорится, не бейте, а если все же будете бить – то не сильно и не ногами.

Поводом для статьи стал виртуальный спор в кругу нескольких весьма продвинутых админов сред виртуализации, а также приближенных к ним лиц, т.е. – меня. Предметом спора была пропускная способность сетей в гипервизоре VMware ESXi, а точнее – производительность паравиртуального сетевого адаптера VMXNET3 в условиях высокой нагрузки. Гугл выдавал на эту тему ссылки типа

http://rickardnobel.se/vmxnet3-vs-e1000e-and-e1000-part-2/

http://www.computertechblog.com/iperf-network-performance-comparison-between-virtual-machines-on-esxi6/

содержащие весьма противоречивые данные, к тому же многие тесты датировались 2012-2014 годами выпуска. Посему ваш покорный слуга принял решение провести небольшое тестирование самостоятельно.

Часть 1. Тестирование конфигурации с настройками по умолчанию.

Никаких особых планов тестирования не писалось. Было только понимание, что производительность – вещь никакая не абстрактная, а очень даже конкретная. Поэтому и измерения тоже должны быть конкретными – берем конкретный хост, конкретную ОС и конкретно измеряем пропускную способность.

«Под рукой» оказался практически незагруженный хост на базе материнской платы ASUS X99-E с процессором Intel Xeon E5-2620 v4 2.1 ГГц, заведомо достаточное количество RAM DDR4 2133. Версия гипервизора ESXi 6.5.0 Update 1 (Build 5969303).

Первым делом были созданы две ВМ с параметрами 4vCPU, 4 Gb RAM (All locked), 40 Gb disk (on paravirtual SCSI controller), сетевой адаптер VMXNET3. Версия ВМ – 13.

В каждую ВМ был установлен Windows Server 2012R2 со всеми обновлениями на 19.10.2017 и VMware Tools 10.1.7 (Build 5541682). Брандмауэр Windows выключен. На сетевые адаптеры внутри ВМ назначены статические IP-адреса. Для чистоты эксперимента виртуальные сетевые адаптеры обеих ВМ были подключены в отдельную порт-группу на отдельном виртуальном коммутаторе. Виртуальный коммутатор не подключался ни к одному физическому адаптеру, т.к. исследовалась производительность не конкретной сетевой карты, а паравиртуального адаптера и виртуального коммутатора.

vmxnet3_1_01

Для замеров пропускной способности виртуальной сети между этими двумя ВМ использовался iperf 3.1.3 x64. На основании прошлого опыта использования iperf было принято решение тестировать несколько раз, с изменением количества TCP потоков от 1 до 16.

ВМ TEST2 выполняла роль сервера (команда iperf –s). Чтобы уж совсем придать «академичность» тестированию в соответствии с остатками моих знаний по метрологии замеры производились 3 раза (для последующего усреднения результатов) по 20 секунд, с паузой в 3 секунды. Предварительные измерения показали наличие артефактов (или, если угодно – статистических выбросов) в первые несколько секунд измерений:

vmxnet3_1_02

Поэтому первые 5 секунд после запуска теста решено было отбрасывать и не учитывать в результатах измерений. Благо у iperf для этого есть специальная опция –O. Также трижды производились замеры в обратном направлении трафика (опция iperf -R). Для всего этого на ВМ TEST1 был написан и запущен небольшой скрипт:

В результате были получены следующие сырые данные: <файл testresult01.log>

Offtopic: команда ECHO %date% %time% была включена в скрипт чтобы примерно отслеживать время выполнения тестов. Команда прекрасно работала из командной строки, в скрипте же выдавала почему-то один и тот же результат. Разбираться не стал. В следующем скрипте заменил

на

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

table01

vmxnet3_1_03

Налицо два явления: плавный рост пропускной способности до 8 потоков, а затем снижение и почти стабилизация. И различие скорости передачи в зависимости от направления. Последнее заинтересовало, и для проверки был проведен аналогичный замер, при котором ВМ «поменяли ролями»: TEST1 стала сервером, скрипт же выполнялся на TEST2. Результаты этого теста были аналогичными, для сокращения объема статьи их не привожу, но и объяснения им, кроме как «это особенность работы iperf в данной среде» на этот момент не было.

Часть 2. Оптимизация.

Нет ничего, что человек, а в особенности – админ среды виртуализации, не мог бы сделать лучше. Наверное. 20 гигабит в секунду на 8 TCP-потоках на дефолтных настройках были неплохим результатом, но я попытался его улучшить. Кто же знал, что все будет совсем не так просто, как предполагалось…

Включаем JUMBO FRAME.

Первое, что пришло на ум: пропускную способность можно повысить, включив Jumbo packet, т.е. увеличив MTU сетевого адаптера до 9000. В реальности, чтобы это работало, нужно, разумеется, чтобы все коммутаторы и маршрутизаторы между хостами также поддерживали MTU 9000. Поэтому включаем Jumbo frame в нашем виртуальном коммутаторе:

vmxnet3_1_04

И смело лезем на обоих ВМ в настройки сетевого адаптера и делаем так:

vmxnet3_1_05

Кстати, эту же настройку можно делать через PowerShell командой

А смотреть все настройки адаптера командой

vmxnet3_1_06

Запускаем немного подправленный скрипт:

и идем пить чай с печеньками, ибо молотить он будет, по данным предыдущего замера, около часа. И действительно: <файл testresult02.log>

Парсим:

table02
Для удобства сравнения накладываем график MTU 9000 на ранее полученный с MTU 1500:

vmxnet3_1_07

Поведение графика «Туда» логично и немного предсказуемо. Но вот «Обратно» преподносит сюрприз. Особенно если сравнить значения второго «реверсного» замера с первым и третьим при TCP от 9 (выделено в таблице выше серым и зеленым): второй замер с опцией –R показывает шикарный результат 27 гигабит в секунду, но предыдущий и следующий замеры явно лажают. Это «ж-ж-ж» случилось явно неспроста, повторный тест с «обменом ролями», когда TEST1 стал сервером, а ТЕСТ2 – клиентом, это подтвердил: <файл testresult02-1.log>

table03
27 гигабит в секунду по сравнению с дефолтными 20-ю – неплохой, но нестабильный результат, поэтому было принято решение найти, «кто же там жужжит».

Часть 3. Поиск «ж-ж-ж».

Далее последовали: курение файн и факинг мануалов, множество тестовых запусков, тяжелые раздумья, снова курение мануалов и далее по кругу. Тест упорно показывал то 27 гигабит, то не поднимался выше 20. Единственным моим предположением, объясняющим происходящее, стало следующее: 20 с гаком гигабит в секунду – трафик, на обработку которого в виртуальном коммутаторе хост обязан потратить ощутимое количество процессорного времени. В случае, если это процессорное время шедулер распределяет «условно оптимально» и не пересекает с нагрузкой от ВМ – мы имеем тест со скоростью 27 гигабит. Если же «ошибается» – ВМ конфликтует за ядро pCPU с обработчиком виртуального коммутатора, и скорость теста падает.

Для косвенного подтверждения этого предположения я выставил обеим ВМ Scheduling Affinity на «четные» pCPU:

vmxnet3_1_08

vmxnet3_1_09

Offtopic: тут я несколько раз вводил «8,10,12,14» , но после нажатия Save и повторно Edit веб клиент упорно показывает «10,12,14,8». Ну да и бог с ним, вроде работает правильно.

 

Тест стал проходить намного стабильнее, esxtop показал косвенное подтверждение моего предположения:

vmxnet3_1_10

Т.к. на хосте запущены только две мои тестовые ВМ, и для них обеих прописано Scheduling Affinity на pCPU, соответствующие физическим ядрам без гипертрейдинга – эти, в красной рамочке, периодически «прыгающие» между «нечетными» (гипертрейдинговыми) pCPU 50-70 процентов нагрузки и есть, по всей видимости, процессорное время, требуемое хосту для обработки трафика внутри виртуального коммутатора.

ВМ с Affinity – не лучшее решение, но другого я пока не нашел. Копал в сторону «можно ли выделить отдельный pCPU для работы процесса виртуального коммутатора» – не преуспел. Зато в результате мы имеем стабильно проходящий тест iperf между двумя виртуальными машинами: <файл testresult04.log >

table04

vmxnet3_1_11
Итого – имеем скорость «без какой-то копеечки» 30 гигабит в секунду.
При этом настройки адаптера в обеих ВМ выглядят так:
vmxnet3_1_12
Единственное отличие в этой картинке от аналогичной, приведенной ранее:

С «Enabled» или пустым полем производительность теста была ниже.По аналогии с «Включаем JUMBO FRAME» планировалось также «Включаем Receive Side Scaling», и «Настраиваем размеры буферов приема и буферов передачи», и даже «Меняем количество vCPU», однако реальность оказалась суровее. Перепробована куча вариантов настроек и ВМ, и сетевого адаптера. Описывать каждую нет смысла, т.к. результат теста они не улучшали. Поэтому за кадром остались некоторые очевидные и не совсем вещи, о которых имеет смысл сказать:

  • Уменьшение количества vCPU в тестовых ВМ ведет к уменьшению значений в тестах. Увеличение – тоже. Возможно, на хосте с большим количеством ядер в процессоре будет иначе. Хотя я в этом сомневаюсь – ни в одном тесте ни один из процессоров внутри ВМ не показал полку в 100%.
  • Включение Receive Side Scaling (RSS) в настройках сетевого адаптера в отсутствии собственно физического адаптера, этот RSS реализующий, ведет к падению пропускной способности теста. А еще там есть хитрый параметр RSS Base Processor Number, логику работы которого удалось постичь не сразу: https://docs.microsoft.com/ru-ru/windows-hardware/drivers/network/setting-the-number-of-rss-processors

Выводы:

Паравиртуальный адаптер VMXNET3 – это жутко близко и запредельно быстро.

Планы: Попробовать то же самое с Linux-based оерационной системой. Например, с активно применяемой мной в жизни RouterOS Cloud Hoster Router. Вооруженный новыми знаниями я попробую штурмануть рубеж в 40 гигабит в секунду между ВМ.

P.S. А вот тут архив с результатами работы скрипта testresult0#.log.

Тестирование производительности VMXNet3. Часть 2: RouterOS Cloud Hosted Router

5 thoughts on “Тестирование производительности VMXNet3. Часть 1: Windows”

  1. Спасибо за статью. Если интересно, в вашем batch-скрипте не работал вывод “ECHO %date% %time%>>testresult01.log” потому что не была включена опция EnableDelayedExpansion и вы неправильно обращались к переменным. Если эта опция не установлена, то CMD высчитывает переменные на стадии парсинга. В вашем случае нужно чтобы расчёт переменных происходил в runtime. Для этого необходимо добавить команду SETLOCAL EnableDelayedExpansion и получать текущее значение переменных с помощью !time! (%time% будет содержать значение при инициализации). Либо сделать цикл с помощью IF и CALL и ручным увеличением переменной, вместо FOR /L.

  2. Благодарю покорнейше за уточнение! Так и знал, что где-то там порывшаяся собака присутствует, но времени разбираться не было. Скрипт исправлю.

  3. Было бы интересно посмотреть, как подействует общая Advanced настройка хоста
    Net.NetVMTxType = 3
    (выделение на каждый виртуальный ethernet от 2 до 8 transmit threads)
    на скорость передачи локального трафика

  4. В “vSphere 6 Foundations Exam Official Cert Guide” советуют не использовать vmxnet3 для Jumbo Frame в гостевой ОС:
    “However, there is a known issue with the vrnxnet3, so you should choose either the vmxnet2 (enhanced vmxnet) or the el000 vnic, whichever is best for the OS on the VM.”

    Я прям озадачился, т.к. считаю vmxnet3 “must-have”. С ходу обнаружил только “Large packet loss at the guest operating system level on the VMXNET3 vNIC in ESXi (2039495)”.

Leave a Reply

Your email address will not be published. Required fields are marked *